1 常见问题
1.1 线程协作
1)Object中
- wait:让出锁,阻塞等待
- notify/notifyAll:唤醒wait的进程,注意,具体唤醒哪一个要看优先级,同优先级的看运气
public class NotifyTest {
public static void main(String[] args) {
byte[] lock = new byte[0];
Thread t1 = new Thread(() -> {
synchronized (lock) {
try {
lock.wait();
System.out.println("t1 started");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
try {
lock.wait();
System.out.println("t2 started");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t3 = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(1000);
System.out.println("t3 notify");
lock.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.setPriority(1);
t2.setPriority(3);
t3.setPriority(2);
t1.start();
t2.start();
t3.start();
}
}
2)Thread中
- sleep:暂停一下,只是让出CPU的执行权,并不释放锁。
public class SleepTest {
public static void main(String[] args) {
final byte[] lock = new byte[0];
new Thread(() -> {
synchronized (lock) {
System.out.println("start");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end");
}
}).start();
new Thread(() -> {
synchronized (lock) {
System.out.println("need lock");
}
}).start();
}
}
新的thread无法异步执行,被迫等待锁,跟着sleep。
- yield:不释放锁,运行中转为就绪,让出cpu给大家去竞争。当然有可能自己又抢了回来
public class YieldTest {
public static void main(String[] args) throws InterruptedException {
final byte[] lock = new byte[0];
//让出执行权,但是锁不释放
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("start");
Thread.yield();
System.out.println("end");
}
});
//可以抢t1,但是拿不到锁,白费
Thread t2 = new Thread(() -> {
synchronized (lock) {
System.out.println("need lock");
}
});
//不需要锁,可以抢t1的执行权,但是能不能抢得到,不一定
//所以多执行几次,会看到不同的结果……
Thread t3 = new Thread(() -> {
System.out.println("t3 started");
});
t1.start();
t2.start();
t3.start();
}
}
分析:
t3会插队抢到执行权,但是t2不会,因为t2和t1共用一把锁而yield不会释放
t3不见得每次都能抢到。可能t1让出又抢了回去
- join:父线程等待子线程执行完成后再执行,将异步转为同步。注意调的是子线程,阻断的是父线程
public class JoinTest implements Runnable {
@Override
public void run()