java 多线程之间的通信
来源:互联网 发布:原油指数软件 编辑:程序博客网 时间:2024/05/01 10:39
在多线程的编码实现中,往往每个线程之间是相互协作实现的,或者说是有先后顺序的,多线程之间的通信能够避免对同一共享变量的争夺。
一、wait()和 notify()
1. wait()方法使得当前线程必须要等待,等到另外一个线程调用notify()或者notifyAll()方法。 当前的线程必须拥有当前对象的monitor,也即lock,就是锁。 线程调用wait()方法,释放它对锁的拥有权,然后等待另外的线程来通知它(通知的方式是notify()或者notifyAll()方法),这样它才能重新获得锁的拥有权和恢复执行。 要确保调用wait()方法的时候拥有锁,即,wait()方法的调用必须放在synchronized方法或synchronized块中。 一个小比较: 当线程调用了wait()方法时,它会释放掉对象的锁。 另一个会导致线程暂停的方法:Thread.sleep(),它会导致线程睡眠指定的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。2. notify()方法会唤醒一个等待当前对象的锁的线程。 如果多个线程在等待,它们中的一个将会选择被唤醒。这种选择是随意的,和具体实现有关。(线程等待一个对象的锁是由于调用了wait方法中的一个)。 **被唤醒的线程是不能被执行的,需要等到当前线程放弃这个对象的锁。** 被唤醒的线程将和其他线程以通常的方式进行竞争,来获得对象的锁。也就是说,被唤醒的线程并没有什么优先权,也没有什么劣势,对象的下一个线程还是需要通过一般性的竞争。 和 wait()方法一样,notify方法调用必须放在synchronized方法或synchronized块中。
import java.util.ArrayList;import java.util.List;public class MyList { private static List<String> list = new ArrayList<String>(); public static void add() { list.add("anyString"); } public static int size() { return list.size(); }}public class ThreadA extends Thread { private Object lock; public ThreadA(Object lock) { super(); this.lock = lock; } @Override public void run() { try { synchronized (lock) { if (MyList.size() != 5) { System.out.println("wait begin " + System.currentTimeMillis()); lock.wait(); System.out.println("wait end " + System.currentTimeMillis()); } } } catch (InterruptedException e) { e.printStackTrace(); } }}public class ThreadB extends Thread { private Object lock; public ThreadB(Object lock) { super(); this.lock = lock; } @Override public void run() { try { synchronized (lock) { for (int i = 0; i < 10; i++) { MyList.add(); if (MyList.size() == 5) { lock.notify(); System.out.println("已经发出了通知"); } System.out.println("添加了" + (i + 1) + "个元素!"); Thread.sleep(1000); } } } catch (InterruptedException e) { e.printStackTrace(); } }}public class Run { public static void main(String[] args) { try { Object lock = new Object(); ThreadA a = new ThreadA(lock); a.start(); Thread.sleep(50); ThreadB b = new ThreadB(lock); b.start(); } catch (InterruptedException e) { e.printStackTrace(); } }}
线程A要等待某个条件满足时(list.size()==5),才执行操作。线程B则向list中添加元素,改变list 的size。A,B之间如何通信的呢?也就是说,线程A如何知道 list.size() 已经为5了呢?这里用到了Object类的 wait() 和 notify() 方法。当条件未满足时(list.size() !=5),线程A调用wait() 放弃CPU,并进入阻塞状态。当条件满足时,线程B调用 notify()通知 线程A,所谓通知线程A,就是唤醒线程A,并让它进入可运行状态。
二、synchronized 关键字
public class MyObject { synchronized public void methodA() { //do something.... } synchronized public void methodB() { //do some other thing }}public class ThreadA extends Thread { private MyObject object;//省略构造方法 @Override public void run() { super.run(); object.methodA(); }}public class ThreadB extends Thread { private MyObject object;//省略构造方法 @Override public void run() { super.run(); object.methodB(); }}public class Run { public static void main(String[] args) { MyObject object = new MyObject(); //线程A与线程B 持有的是同一个对象:object ThreadA a = new ThreadA(object); ThreadB b = new ThreadB(object); a.start(); b.start(); }}
由于线程A和线程B持有同一个MyObject类的对象object,尽管这两个线程需要调用不同的方法,但是它们是同步执行的,比如:线程B需要等待线程A执行完了methodA()方法之后,它才能执行methodB()方法。这样,线程A和线程B就实现了通信。这种方式,本质上就是“共享内存”式的通信。多个线程需要访问同一个共享变量,谁拿到了锁(获得了访问权限),谁就可以执行。
0 0
- java多线程之间的通信
- Java多线程之间的通信
- java 多线程之间的通信
- java多线程之间通信
- java多线程(三)线程之间的通信
- Java---17---多线程之间的通信
- java 多线程 线程之间的通信
- 多线程之间的通信
- 多线程之间的通信
- 多线程之间的通信
- 多线程之间的通信
- 多线程之间的通信
- java Condition多线程之间通信
- 模拟多线程之间的通信
- 多线程-线程之间的通信
- Windows多线程之间的通信
- 223,多线程之间的通信
- 黑马程序员:Java基础——多线程之间的通信
- Redis安装使用教程
- debian中查找已安装软件及卸载软件
- 想写UInavibar
- 给datagridview添加行数
- oracle定时任务导数据库
- java 多线程之间的通信
- C++中临时对象及返回值优化
- 前端安全问题:CSRF
- HDU 5547(DFS)
- APP测试学习笔记1--android恶意代码分析
- Android Binder设计与实现(2) – 设计篇
- 三极管电路分析
- 浅谈 C++ 中的 new/delete 和 new[]/delete[]
- Unit3 文档