1 thread.join()
使用.join方法时需要进行加锁,当线程调用.join()方法时,调用此方法的线程会被阻塞在方法调用处,等到等待的线程执行完毕或者运行超时的时候,便会会释放掉锁,调用此方法的线程才会继续执行
2 wait(),notify()和notifyAll()
wait():因为wait方法会进行加锁,所以wait方法执行前会先占用锁资源,wait方法执行时会释放掉锁资源,但是代码还停在此处,等待超时或者notify(),notifyAll()唤醒,被notify()和notifyAll()唤醒后,还需要重新竞争锁资源
notify():notify()方法会先占用锁资源,然后随机唤醒一个使用此锁资源的调用了wait方法的线程,使线程竞争锁资源,继续运行
notifyAl():notfyAll()方法与notify()的功能类似,但是notifyAll方法不是随机唤醒,而是将需要此锁资源的线程全部唤醒,让他们进行竞争,谁抢到锁资源,谁就执行
3 wait方法与join方法的区别
wait方法与join方法的应用场景不同,join方法是在等待线程结束运行时才能继续执行,而wait方法是只要被唤醒就会继续重新进行锁竞争,继续执行,join是以整个线程的结束为判断的,wait是以是否被notify唤醒为判断的
join,wait,notify,notifyAll都必须要搭配synchronized进行使用,而且wait,notify,notifyAll使用的锁资源必须是相同的,notify,notifyAll多执行是没关系的
public static void main(String[] args) {
//定义一个锁对象
Object locker = new Object();
//创建调用wait()的线程
Thread t1 = new Thread(()->{
while(true){
System.out.println("wait之前");
try {
//加锁
synchronized(locker){
locker.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait之后");
System.out.println("=========================================");
}
},"wait");
//启动t1
t1.start();
Thread t2 = new Thread(()->{
while(true){
System.out.println("notify之前");
//加锁
synchronized(locker){
locker.notify();
}
System.out.println("notify之后");
try {
//休眠一会儿,另一种休眠方式,使用并发包里的工具类
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"notify");
t2.start();
}
t1线程先打印wait之前,然后进入wait方法,线程堵塞,释放锁资源,t2线程打印notify之前,申请锁资源,唤醒t1线程重新竞争锁,t2线程打印notify之后,t2线程释放锁,t1线程占用锁资源继续执行打印wait之后