这篇文章主要介绍“Java怎么使用wait或notify实现线程间通信”,在日常操作中,相信很多人在Java怎么使用wait或notify实现线程间通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎么使用wait或notify实现线程间通信”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
当线程调用锁对象的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);
}
}
执行结果:
调用方法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中的线程。
前面的示例中通过多次调用 notify() 方法来实现唤醒3个线程,但并不能保证系统中仅有3个线程,也就是若notify()方法的调用次数小于线程对象的数量,会出现有部分线程对象无法被唤醒的情况。为了唤醒全部线程,可以使用notifyAll()方法。
更改代码如下:
再次运行,程序运行效果如图所示,可以看出所有的线程全部被唤醒。
带一个参数的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实现线程间通信”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。