Java之thread常用成员
setName用于自定义线程的名字,方便我们调试定为问题;
@Test
public void setNameTest(){
Runnable run = ()->{
System.out.println(Thread.currentThread().getName());
};
var t1 = new Thread(run);
t1.start();
var t2 = new Thread(run);
t2.setName("t2");
t2.start();
// Thread-0
// t2
}
sleep是静态方法会暂停当前线程的执行
@Test
public void sleepTest() throws InterruptedException {
var t1 = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
});
t1.setName("t1");
t1.start();
var t2 = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t2.setName("t2");
t2.start();
t1.join();
t2.join();
// t1:0
// t1:1
// t1:2
// t2:0
// t1:3
// t1:4
// t1:5
// t1:6
// t1:7
// t1:8
// t1:9
// t2:1
// t2:2
// t2:3
// t2:4
// t2:5
// t2:6
// t2:7
// t2:8
// t2:9
}
线程的yield(让步)操作的作用是让目前正在执行的线程放弃当前的执行,让出CPU的执行权限,使得CPU去执行其他的线程。处于让步状态的JVM层面的线程状态仍然是RUNNABLE状态,但是该线程所对应的操作系统层面的线程从状态上来说会从执行状态变成就绪状态。线程在yield时,线程放弃和重占CPU的时间是不确定的,可能是刚刚放弃CPU,马上又获得CPU执行权限,重新开始执行。
@Test
public void yieldTest() throws InterruptedException {
var t1 = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
});
t1.setName("t1");
t1.setPriority(Thread.MIN_PRIORITY);
var t2 = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
if(i % 3 == 0){
Thread.yield();
}
}
});
t2.setName("t2");
t2.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
t1.join();
t2.join();
// t2:0
// t2:1
// t2:2
// t2:3
// t1:0
// t2:4
// t1:1
// t2:5
// t2:6
// t1:2
// t2:7
// t1:3
// t2:8
// t1:4
// t2:9
// t1:5
// t1:6
// t1:7
// t1:8
// t1:9
}
调用join()方法的语句可以理解为合并点,合并的本质是:线程A需要在合并点等待,一直等到线程B执行完成,或者等待超时。
@Test
public void joinTest() throws InterruptedException {
var t1 = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
});
t1.setName("t1");
var t2 = new Thread(()-> {
for (int i = 0; i < 10; i++) {
if(i == 3){
try {
t1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(Thread.currentThread().getName() + ":" + i);
}
});
t2.setName("t2");
t1.start();
t2.start();
t2.join();
// t2:0
// t2:1
// t2:2
// t1:0
// t1:1
// t1:2
// t1:3
// t1:4
// t1:5
// t1:6
// t1:7
// t1:8
// t1:9
// t2:3
// t2:4
// t2:5
// t2:6
// t2:7
// t2:8
// t2:9
}
Java线程的最大优先级值为10,最小值为1,默认值为5,优先级只是一个相对值,并不是高优先级的必然先执行完;
@Test
public void priorityTest() throws InterruptedException {
var t1 = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
});
t1.setPriority(Thread.MAX_PRIORITY);
var t2 = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
});
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t1.join();
t2.join();
// Thread-0:0
// Thread-0:1
// Thread-1:0
// Thread-0:2
// Thread-1:1
// Thread-1:2
// Thread-1:3
// Thread-1:4
// Thread-1:5
// Thread-1:6
// Thread-1:7
// Thread-0:3
// Thread-1:8
// Thread-0:4
// Thread-1:9
// Thread-0:5
// Thread-0:6
// Thread-0:7
// Thread-0:8
// Thread-0:9
}