这篇文章主要介绍“Java怎么使用wait或notify实现线程间通信”,在日常操作中,相信很多人在Java怎么使用wait或notify实现线程间通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎么使用wait或notify实现线程间通信”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
1. 当 interrupt() 方法遇到 wait() 方法
当线程调用锁对象的wait() 方法使线程呈等待状态时,调用线程对象的 interrupt() 方法会出现 InterruptedException 异常。
public class ThreadC7 { @Test public void test1() { try { Object obj = new Object(); ThreadC7A threadC7A = new ThreadC7A(obj); threadC7A.start(); Thread.sleep(2000); threadC7A.interrupt(); } catch (Exception e) { e.printStackTrace(); } }}class ServiceC7 { public void testMethod(Object obj) { try { synchronized (obj) { System.out.println("begin wait"); obj.wait(); System.out.println("begin end"); } } catch (Exception e) { e.printStackTrace(); System.out.println("出现异常了,wait状态的线程被interrupt了!"); } }}class ThreadC7A extends Thread { private Object obj; public ThreadC7A(Object obj) { this.obj = obj; } @Override public void run() { ServiceC7 serviceC7 = new ServiceC7(); serviceC7.testMethod(obj); }}
执行结果:
2. notify() 只通知一个线程
调用方法notify()一次只随机通知一个线程进行唤醒。
public class ThreadC8 { @Test public void test() { Object obj = new Object(); ThreadC8A threadC8A = new ThreadC8A(obj); threadC8A.setName("threadC8A"); threadC8A.start(); ThreadC8B threadC8B = new ThreadC8B(obj); threadC8B.setName("threadC8B"); threadC8B.start(); ThreadC8C threadC8C = new ThreadC8C(obj); threadC8C.setName("threadC8C"); threadC8C.start(); try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } synchronized (obj) { obj.notify(); } while (Thread.activeCount() > 1) { } }}class ServiceC8 { public void service(Object obj) { try { synchronized (obj) { String threadName = Thread.currentThread().getName(); System.out.println("begin wait,Thread Name:[" + threadName + "]"); obj.wait(); System.out.println("end wait,Thread Name:[" + threadName + "]"); } } catch (Exception e) { e.printStackTrace(); } }}class ThreadC8A extends Thread { private Object obj; public ThreadC8A(Object obj) { this.obj = obj; } @Override public void run() { ServiceC8 serviceC8 = new ServiceC8(); serviceC8.service(obj); }}class ThreadC8B extends Thread { private Object obj; public ThreadC8B(Object obj) { this.obj = obj; } @Override public void run() { ServiceC8 serviceC8 = new ServiceC8(); serviceC8.service(obj); }}class ThreadC8C extends Thread { private Object obj; public ThreadC8C(Object obj) { this.obj = obj; } @Override public void run() { ServiceC8 serviceC8 = new ServiceC8(); serviceC8.service(obj); }}
执行结果:
程序运行的效果如图所示,可以看出方法notify()仅随机唤醒一个线程。
当多次调用notify()方法时,会随机将等待wait状态的线程进行唤醒。更改代码如下:
再次运行,程序运行效果如图所示,可以看出所有的线程全部被唤醒。
多次调用notify()方法可唤醒全部WAITING中的线程。
3. notifyAll() 唤醒所有线程
前面的示例中通过多次调用 notify() 方法来实现唤醒3个线程,但并不能保证系统中仅有3个线程,也就是若notify()方法的调用次数小于线程对象的数量,会出现有部分线程对象无法被唤醒的情况。为了唤醒全部线程,可以使用notifyAll()方法。
更改代码如下:
再次运行,程序运行效果如图所示,可以看出所有的线程全部被唤醒。
4. 方法 wait(long)的使用
带一个参数的wait(long) 方法的功能是等待某一时间内是否有现成对锁进行唤醒,如果超过这个时间则自动唤醒。
public class ThreadC9 { @Test public void test() { Object obj = new Object(); ThreadC9A threadC9A = new ThreadC9A(obj); threadC9A.start(); while (Thread.activeCount() > 1) { } }}class ThreadC9A extends Thread { private Object obj; public ThreadC9A(Object obj) { this.obj = obj; } @Override public void run() { try { synchronized (obj) { long startTime = System.currentTimeMillis(); System.out.println("begin wait,time:[" + startTime + "]"); obj.wait(5000); long endTime = System.currentTimeMillis(); System.out.println("end wait,time:[" + endTime + "] takes " + (endTime - startTime) + " ms"); } } catch (Exception e) { e.printStackTrace(); } }}
执行结果:
通过执行结果可以看出,在经过5000ms后,线程被唤醒。
到此,关于“Java怎么使用wait或notify实现线程间通信”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!