多线程使用方式

线程睡眠

  在需要睡眠的线程中添加一行Thread.sleep(long millis)

1
2
3
4
5
6
7
8
9
10
new Thread(new Runnable{
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();

线程名称

  设置线程名称

1
2
3
4
5
6
7
8
Thread thread = new Thread() {
@Override
public void run() {
super.run();
}
};
// 设置线程名
thread.setName("test");

  获取线程名称

1
2
3
4
5
6
7
8
9
Thread thread = new Thread() {
@Override
public void run() {
super.run();
}
};
thread.setName("test");
// 获取线程名
System.out.println(thread.getName());

获取当前线程

  在main(String[] args)方法主线程中获取当前线程,并输出线程名称

1
2
3
4
public static void main(String[] args) {
Thread currentThread = Thread.currentThread();
System.out.println(currentThread.getName());
}

  将会输出

1
main

线程优先级

  线程优先级的范围是从1-10,默认是5,数值越大优先级越高,优先级高的线程获得的CPU资源较多

1
2
3
4
5
6
7
8
Thread thread = new Thread(new Runnable() {
@Override
public void run() {

}
});
thread.setPriority(10); // 设置优先级
int priority = thread.getPriority(); // 获取优先级

  如下代码,线程1的优先级设置为5,线程2的优先级设置为10,执行发现线程2几乎每次都在线程1之前执行完毕

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class NewThread extends Thread {

public static void main(String[] args) {
// 线程1 循环100次
NewThread thread1 = new NewThread();
thread1.setName("线程1");
// 设置优先级
thread1.setPriority(5);
thread1.start();

// 线程2 循环100次
NewThread thread2 = new NewThread() ;
thread2.setName("线程2");
// 设置优先级
thread2.setPriority(10);
thread2.start();
}

@Override
public void run() {
super.run();
for (int i = 1; i <= 100; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + "第" + i + "轮任务");
}
}
}

守护线程

  如果一个线程没有设置守护线程或非守护线程,那么它的状态取决于父类是否为守护线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class NewThread extends Thread {

public static void main(String[] args) {
NewThread newThread = new NewThread();

// 设置守护线程 true:守护线程 false:非守护线程
newThread.setDaemon(true);

// 线程是否是守护线程
boolean daemon = newThread.isDaemon();
}

@Override
public void run() {
super.run();
}
}

  当所有非守护线程执行完成或退出后,守护线程会随即终止
  如下代码,当非守护线程中的循环执行完50次结束后,守护线程此时执行了大概40-80轮,并随着非守护线程结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class NewThread extends Thread {

public static void main(String[] args) {
// 线程1 非守护线程
NewThread thread1 = new NewThread();
thread1.setDaemon(false);
thread1.start();

// 线程2 守护线程
NewThread thread2 = new NewThread();
thread2.setDaemon(true);
thread2.start();
}

@Override
public void run() {
super.run();
// 是否是守护线程
boolean daemon = isDaemon();
if (daemon) {
for (int i = 1; i <= 500; i++) {
System.out.println("守护线程,执行第" + i + "轮");
}
} else {
for (int i = 1; i <= 50; i++) {
System.out.println("用户线程,执行第" + i + "轮");
}
}
}
}

礼让线程

  使当前线程暂停执行,让出CPU资源给其他线程。调用Thread..yield()方法后,线程将从运行状态转变为就绪状态,然后重新竞争CPU资源。这会使得如下代码的输出结果相对之前变得均匀

  当线程调用Thread.yield()方法后,它并不会立即重新竞争CPU资源,而是进入就绪状态,与其他就绪状态的线程竞争CPU资源,这样可以给其他线程更多的机会来执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class NewThread extends Thread {

public static void main(String[] args) {
NewThread thread1 = new NewThread();
thread1.setName("线程1");
thread1.start();

NewThread thread2 = new NewThread();
thread2.setName("线程2");
thread2.start();
}

@Override
public void run() {
super.run();
for (int i = 1; i <= 100; i++) {
System.out.println(getName() + "第" + i + "轮");
// 将线程设置为礼让线程
Thread.yield();
}
}
}

插入线程

join()

  thread.join()使当前线程等待thread线程完成其执行后,继续向下执行当前线程。

  如下代码,当一个线程通过调用thread.start()方法启动后,主线程会继续执行而不等待该线程完成。如果想让主线程等待thread线程完成后再继续执行,可以在thread.start()后调用thread.join()方法,阻塞主线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static void main(String[] args) {
Thread thread = new Thread() {
@Override
public void run() {
super.run();
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在执行" + getName() + "第" + i + "轮");
}
}
};
thread.setName("thread");
thread.start();

try {
// 阻塞main线程,在thread执行完毕后main线程继续向下执行
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println(currentThread().getName() + "线程执行完毕");
}

  将会输出

1
2
3
4
5
6
正在执行thread第1轮
正在执行thread第2轮
...
正在执行thread第19轮
正在执行thread第20轮
main线程执行完毕

  如下代码,在执行thread2时会等待thread1执行完毕,而执行thread3又会等待thread2执行完毕,所以将会按照thread1thread2thread3的执行顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public static void main(String[] args) {
Thread thread1 = new Thread() {
@Override
public void run() {
super.run();
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在执行" + getName() + "第" + i + "轮");
}
}
};
thread1.setName("thread1");

Thread thread2 = new Thread() {
@Override
public void run() {
super.run();

try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在执行" + getName() + "第" + i + "轮");
}
}
};
thread2.setName("thread2");

Thread thread3 = new Thread() {
@Override
public void run() {
super.run();

try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在执行" + getName() + "第" + i + "轮");
}
}
};
thread3.setName("thread3");

thread1.start();
thread2.start();
thread3.start();
}

join(long millis)

  最多等待被join的线程millis秒,millis后不再等待

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public static void main(String[] args){
Thread thread1 = new Thread() {
@Override
public void run() {
super.run();
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在执行" + getName() + "第" + i + "轮");
}
}
}
thread1.setName("thread1");

Thread thread2 = new Thread() {
@Override
public void run() {
super.run();
// 最多等1000ms,1000ms内thread1没有执行结束,不再等待
thread1.join(1000);
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在执行" + getName() + "第" + i + "轮");
}
}
}
thread2.setName("thread2");

thread2.start();
thread3.start();
}

join(long millis, int nanos)

  最多等待被join的线程millis + nanos秒,millis + nanos后不再等待