原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11398563.html
notify() 和 wait() 主要是用来多个线程之间的协作。
它们都是Object的方法,任何对象都可以调用这两个方法。
首先设置一个多个线程共享的对象 :
//共享对象
Object shareObject = new Object();
1.wait() :导致当前线程等待,直到另一个线程调用该对象的notify()或者notifyAll()方法;
这里用代码解释一下:
class ThreadOne extends Thread{ @Override public void run() { synchronized (shareObject){ for (int i = 0; i < 10 ; i++){ System.out.println("A线程--->"+i); shareObject.notify(); if (first){ first = false; try { shareObject.wait(); } catch (Exception e){ System.out.println(e); } } } } } }
这里的 shareObject.wait(); 会导致ThreadOne线程进入shareObject对象的等待队列(这个等待队列可能会有多个线程,这些线程都停止继续执行,进入等待状态),直到其他线程调用shareObject的notify()或者notifyAll()方法,ThreadOne线程就可能会被唤醒,因为该唤醒是从等待队列中随机抽取一个线程进行唤醒,不公平唤醒。
2.notify() :唤醒正在等待对象监视器的单个线程。这个在上面已经作了解释,下面用代码说明一下。
class ThreadTwo extends Thread{ @Override public void run() { synchronized (shareObject){ for (int i = 0; i < 10; i++){ System.out.println("B线程--->"+i); shareObject.notify(); if (!first){ first = true; try { shareObject.wait(); }catch (Exception e){ System.out.println(e); } } } } } }
这里的 shareObject.notify();会从shareObject对象的等待队列中随机唤醒一个线程,但是目前的shareObject对象的等待队列中只有ThreadOne一个线程,所以它就被唤醒了。
过程如下图:
最后:wait和sleep区别
1️⃣ wait和sleep方法都可以让线程等待;
2️⃣ wait()方法可以被唤醒,sleep不能被唤醒。
3️⃣ wait()既会释放cpu,也会释放共享资源的锁,sleep()不会释放任何资源。
4️⃣ wait和sleep方法都可以使线程进人阻塞状态。
5️⃣ wait和sleep方法均是可中断方法,被中断后都会收到中断异常。
6️⃣ wait是Object的方法,而sleep是Thread特有的方法。
7️⃣ wait方法的执行必须在同步方法中进行,而sleep则不需要。
8️⃣ 线程在同步方法中执行sleep方法时,并不会释放monitor的锁,而wait方法则会释放monitor的锁。
9️⃣ sleep方法短暂休眠之后会主动退出阻塞,而wait方法(没有指定wait时间)则需要被其他线程中断后才能退出阻塞。
? sleep:是Thread的静态方法,会使当前线程释放cpu,但不会释放锁资源,可以理解为只和cpu有关,不涉及锁资源。涉及锁资源的,是wait,join方法。
?1️⃣ yield:也是Thread的静态方法,和sleep方法类似,会使当前线程释放cpu,但不会释放锁资源。和sleep不同的是,sleep必须设置时间,但是yield不能设置时间,时间值是随机的
?2️⃣ join: 等待join方法执行线程先执行完毕, main方法再继续执行; 例如 main方法中有一个线程thread执行了thread.join() ; 那么当main方法执行到了thread.join()语句时,必须等待thread线程执行完毕,才能继续执行;thread必须执行了start方法才会这样,如果没有执行start方法main方法会直接执行下去.
结束?