多线程之间的通信
来源:互联网 发布:软件外包保密协议 编辑:程序博客网 时间:2024/06/02 07:27
一,概述
1.什么时候需要线程间通信?
* 多个线程并发执行时, 在默认情况下CPU是随机切换线程的。
* 如果我们希望线程间有规律的切换, 就需要进行线程间通信。例如先让线程一执行,然后让线程一和线程二轮流交替执行。
2.怎么实现线程间通信?
实现线程间通信要借助于多线程同步,所以也分为两种方法,一种使用synchronized 关键字实现,另一种使用ReentrantLock 类实现。
二,使用synchronized 关键字实现线程间通信
重要点如下:
* 如果希望线程等待, 就调用wait()方法。
* 如果希望唤醒等待的线程, 就调用notify()方法。
* 这两个方法必须在同步代码中执行, 并且使用同步锁对象来调用。
代码示例如下:
首先声明两个成员方法:
int flag = 1;//定义一个标记public void print01(){ synchronized (this){//this称为同步锁对象 if(flag != 1){ try { this.wait();//调用wait方法,使线程处于等待状态。 } catch (InterruptedException e) { e.printStackTrace(); } } Log.d("kwwl","郭"); Log.d("kwwl","靖"); flag =2; this.notify();//调用notify方法,唤醒线程 }} public void print02(){ synchronized (this){ if(flag == 1){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } Log.d("kwwl","黄"); Log.d("kwwl","蓉"); flag =1; this.notify(); }}
同时开启两个线程,分别调用print01和print02方法,代码如下:
new Thread(new Runnable() { public void run() { while (true) { print01(); } }}).start();new Thread(new Runnable() { public void run() { while (true) { print02(); } }}).start();
在上面print01和print02方法中都使用了synchronized 关键字构成了同步代码块,所以“郭”和“靖”一定同时打印,“黄”和“蓉”一定同时打印。但如果不使用wait方法和notify方法,则会出现“郭靖”打印了很多次才会打印“黄蓉”。而此时使用了wait方法和notify方法,实现了线程间通信功能,则“郭靖”和“黄蓉”轮流交替打印。
说明:this称为同步锁对象,他可以是任意类型的对象,但必须保证两个同步代码块的锁对象是同一个对象。
分析:
假设线程二先执行了,此时判断flag等于1,然后这个线程就会等待,此时线程1就会执行,但线程一执行后flag等于2,并调用notify来唤醒线程,这个方法是随机唤醒使用this锁等待的线程,此时只有线程二处于等待,所以线程二被唤醒。然后若还是线程一执行,那么因为此时flag等于2,所以线程一将被等待,所以就会执行线程二,等等依次执行。
注:如果是三个线程间的通信,可以使用this.notityAll方法,这个方法表示唤醒所有等待的线程。
三,使用ReentrantLock 类实现线程间通信
重要点如下:
*首先创建ReentrantLock 对象,然后再得到Condition 对象。
* 如果希望线程等待, 就调用await()方法。
* 如果希望唤醒等待的线程, 就调用signal()方法。
* 这两个方法必须在同步代码中执行, 并且使用同一个ReentrantLock 对象。
代码示例如下:
首先声明两个成员方法:
int flag = 1;private ReentrantLock lock = new ReentrantLock();Condition c1 = lock.newCondition();Condition c2 = lock.newCondition();public void print01(){ lock.lock(); if(flag != 1){ try { c1.await(); } catch (InterruptedException e) { e.printStackTrace(); } } Log.d("kwwl","郭"); Log.d("kwwl","靖"); c2.signal(); lock.unlock();}public void print02(){ lock.lock(); if(flag != 1){ try { c2.await(); } catch (InterruptedException e) { e.printStackTrace(); } } Log.d("kwwl","黄"); Log.d("kwwl","蓉"); c1.signal();//唤醒c1 lock.unlock();}
再同时开启两个线程,分别调用两个方法,代码同上。
分析:首先使用ReentrantLock 对象的lock和unlock方法实现了同步代码块。然后又使用Condition类的await方法和signal方法实现了等待唤醒机制,实现了线程间通信。
- 多线程之间的通信
- 多线程之间的通信
- 多线程之间的通信
- 多线程之间的通信
- 多线程之间的通信
- java多线程之间的通信
- 模拟多线程之间的通信
- 多线程-线程之间的通信
- Java多线程之间的通信
- Windows多线程之间的通信
- 223,多线程之间的通信
- java 多线程之间的通信
- 如何建立多线程之间的消息通信
- Win32多线程之线程之间的通信
- 多线程之间的通信生产者和消费者
- java多线程(三)线程之间的通信
- Java---17---多线程之间的通信
- Condidtion实现多线程之间的线程通信
- JAVA中纯文本的读与写、拷贝
- C语言笔记2
- IntelliJ手动安装python与scala插件
- HDU
- jsp基础知识小结
- 多线程之间的通信
- ListView的常用优化
- Quartz入门实例14-让Quartz的Job使用Spring注入的Bean
- 代码推送到github,并配置密匙
- SQL Server索引、游标
- 从 Swift 的面向协议编程说开去
- linux进程调度算法:分时调度策略、FIFO调度策略、RR调度策略
- c#设计模式==工厂方法模式
- 小型BBS项目1--4月25号学习总结