温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java怎么使用wait或notify实现线程间通信

发布时间:2022-12-13 09:12:15 来源:亿速云 阅读:113 作者:iii 栏目:开发技术

这篇文章主要介绍“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);
    }
}

执行结果:

Java怎么使用wait或notify实现线程间通信

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);
    }
}

执行结果:

Java怎么使用wait或notify实现线程间通信

程序运行的效果如图所示,可以看出方法notify()仅随机唤醒一个线程。

当多次调用notify()方法时,会随机将等待wait状态的线程进行唤醒。更改代码如下:

Java怎么使用wait或notify实现线程间通信

再次运行,程序运行效果如图所示,可以看出所有的线程全部被唤醒。

Java怎么使用wait或notify实现线程间通信

多次调用notify()方法可唤醒全部WAITING中的线程。

3. notifyAll() 唤醒所有线程

前面的示例中通过多次调用 notify() 方法来实现唤醒3个线程,但并不能保证系统中仅有3个线程,也就是若notify()方法的调用次数小于线程对象的数量,会出现有部分线程对象无法被唤醒的情况。为了唤醒全部线程,可以使用notifyAll()方法。

更改代码如下:

Java怎么使用wait或notify实现线程间通信

再次运行,程序运行效果如图所示,可以看出所有的线程全部被唤醒。

Java怎么使用wait或notify实现线程间通信

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();
        }
    }
}

执行结果:

Java怎么使用wait或notify实现线程间通信

通过执行结果可以看出,在经过5000ms后,线程被唤醒。

到此,关于“Java怎么使用wait或notify实现线程间通信”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI