多线程-线程间通讯
来源:互联网 发布:网络直播发展趋势 编辑:程序博客网 时间:2024/05/12 08:55
线程间通讯示例:
–说明:
Lock接口:替代了同步代码块或者同步函数。将同步的隐式锁操作变成实现锁操作,同时更加灵活,可以一个锁加上多组监视器。
lock():获取锁; unlock();释放锁;通常需要定义在finally代码块中。
Condition接口:替代了Object中的wait notify notifyAll方法,可以将这些监视器方法单独进行封装,变成Condition监视器对象,可以任意进行组合。
方法有:await signal signalAll;
注意: lock()锁是互斥的,表面上可以这样理解。
//大家都需要的公共资源class Resource{ String name; String sex;}//输入class Input implements Runnable{ //定义一个公共资源 Resource r; //用构造器初始化公共资源,利用传入参数的方式初始化。 Input(Resource r) { this.r = r; } //覆盖Thread线程里面的run方法。重写吧。 public void run() { int x = 0; while(true) { //用公共资源加锁。确保输入和输出的锁都是一个锁。(r) synchronized(r) { if(x==0) { r.name = "mike"; r.sex = "man"; } else { e.name = "丽丽"; e.sex = "女"; } } x = (x+1)%2; } }}//输出class Output implements Runnable{ Resource r; Output(Resource r) { this.r = r; } public void run() { int x = 0; synchronized(r) { //将while放在锁的里面是避免while一直进行循环不释放资源 //就会造成一直执行某一个语句或者是函数,不能进行线程的切换。 while(true) { System.out.println(r.name+"...."+r.sex); } } }}class ResourceDemo{ public static void main(String[] args) { //创建资源 Resource r = new Resource(); //创建任务 Input in = new Input(r); Output out = new Output(r); //创建线程,执行任务 Thread t1 = new Thread(in); Thread t2 = new Thread(out); //开启线程 in.start(); out.start(); }}
多线程间通讯—等待唤醒机制
–机制里的方法;
1.wait(); –让线程处于冻结状态,被wait的线程会被保存到线程池中。
2.notify();
3.notifyAll();
注意:这些方法都必须定义在同步中,因为:这些方法是用于操作线程状态的方法,必须要明确,要操作的是那个锁上的线程。
//大家都需要的公共资源class Resource{ String name; String sex; boolean flag = false;}//输入class Input implements Runnable{ //定义一个公共资源 Resource r; //用构造器初始化公共资源,利用传入参数的方式初始化。 Input(Resource r) { this.r = r; } //覆盖Thread线程里面的run方法。重写吧。 public void run() { int x = 0; while(true) { //用公共资源加锁。确保输入和输出的锁都是一个锁。(r) synchronized(r) { if(r.flag) try{ r.wait(); }catch(InterruptionException e){}; if(x==0) { r.name = "mike"; r.sex = "man"; } else { e.name = "丽丽"; e.sex = "女"; } r.flag = true; r.notify(); } x = (x+1)%2; } }}//输出class Output implements Runnable{ Resource r; Output(Resource r) { this.r = r; } public void run() { int x = 0; synchronized(r) { //将while放在锁的里面是避免while一直进行循环不释放资源 //就会造成一直执行某一个语句或者是函数,不能进行线程的切换。 while(true) { if(!r.flag) try{ r.wait(); }catch(InterruptionException e){}; System.out.println(r.name+"...."+r.sex); r.flag = false; r.notify(); } } }}class ResourceDemo{ public static void main(String[] args) { //创建资源 Resource r = new Resource(); //创建任务 Input in = new Input(r); Output out = new Output(r); //创建线程,执行任务 Thread t1 = new Thread(in); Thread t2 = new Thread(out); //开启线程 in.start(); out.start(); }}
将资源的属性封装—示例
//大家都需要的公共资源class Resource{ private String name; private String sex; private boolean flag = false; public synchronized void set(String name, String sex) { if(flag) try{ this.wait(); }catch(InterruptionException e){}; this.name = name; this.sex = sex; flag = true; this.notify(); } public synchronized void out() { if(!flag) try{ this.wait(); }catch(InterruptionException e){}; System.out.println(name+"..."+sex); flag = false; notify(); }}//输入class Input implements Runnable{ //定义一个公共资源 Resource r; //用构造器初始化公共资源,利用传入参数的方式初始化。 Input(Resource r) { this.r = r; } //覆盖Thread线程里面的run方法。重写吧。 public void run() { int x = 0; while(true) { if(x==0) { r.set("mike","man"); } else { r.set("丽丽","女"); } x = (x+1)%2; } }}//输出class Output implements Runnable{ Resource r; Output(Resource r) { this.r = r; } public void run() { int x = 0; while(true) { r.out(); } }}class ResourceDemo{ public static void main(String[] args) { //创建资源 Resource r = new Resource(); //创建任务 Input in = new Input(r); Output out = new Output(r); //创建线程,执行任务 Thread t1 = new Thread(in); Thread t2 = new Thread(out); //开启线程 in.start(); out.start(); }}
多先线程间通信—生产者,消费这问题。
–一个简单的单生产单消费案例
class Resource{ private String name; private int count = 1; private boolean = false; public synchronized void set(String name) { if(flag) try{ this.wait(); }catch(InterruptionException e){}; this.name = name + count; count++; System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name); flag = true; notify(); } public synchronized void out() { if(flag) try{ this.wait(); }catch(InterruptionException e){}; System.out.println(Thread.currentThread().getName()+"...消费者......."+this.name); flag = true; notify(); }}class Producer implements Runnable{ private Resource r; Producer(Resource r) { this.r = r; } public void run() { while(true) { r.set("烤鸭"); } }}class Consumer implements Runnable{ private Resource r; Consumer(Resource r) { this.r = r; } public void run() { while(true) { r.out(); } }}class ProducerConsumerDemo{ public static void main(String[] args) { //创建资源 Resource r = new Resource(); //创建任务 Producer pro = new Producer(r); Consumer con = new Consumer(r); //创建线程,执行任务 Thread t1 = new Thread(pro); Thread t2 = new Thread(con); //开启线程 in.start(); out.start(); }}
多生产多消费问题的示例:
if判断标记,只标记一次,会导致不该运行的程序运行了,出现数组错误的情况。while判断标记,解决了线程获取执行权后,是否要运行。notify只能唤醒一个线程,如果奔放唤醒了本方,没有意义,而且while标记判断notigy会导致死锁。notifyAll解决了本方线程一定会唤醒对方线程的问题。class Resource{ private String name; private int count = 1; private boolean = false; public synchronized void set(String name) { while(flag) try{ this.wait(); }catch(InterruptionException e){}; this.name = name + count; count++; System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name); flag = true; notifyAll(); } public synchronized void out() { while(flag) try{ this.wait(); }catch(InterruptionException e){}; System.out.println(Thread.currentThread().getName()+"...消费者......."+this.name); flag = true; notifyAll(); }}class Producer implements Runnable{ private Resource r; Producer(Resource r) { this.r = r; } public void run() { while(true) { r.set("烤鸭"); } }}class Consumer implements Runnable{ private Resource r; Consumer(Resource r) { this.r = r; } public void run() { while(true) { r.out(); } }}class ProducerConsumerDemo{ public static void main(String[] args) { //创建资源 Resource r = new Resource(); //创建任务 Producer pro = new Producer(r); Consumer con = new Consumer(r); //创建线程,执行任务 Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); Thread t3 = new Thread(con); Thread t4 = new Thread(con); //开启线程 in.start(); out.start(); }}
显式锁的使用示例:
import java.util.concurrent.lock.*;class Resource{ private String name; private int count = 1; private boolean = false; //创建一个锁对象 Lock lock = new ReentrantLock(); //通过已有的锁获取该锁上的监视器对象。 //Condition con = lock.newCondition(); Condition produce_con = lock.newCondition(); Condition consumer_con = lock.newCondition(); public void set(String name) { lock.lock(); try { while(flag) //try{ this.wait(); }catch(InterruptionException e){}; try{ produce_con.await(); }catch(InterruptionException e){}; this.name = name + count; count++; System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name); flag = true; //notifyAll(); //con.notifyAll(); consumer_con.signal(); }finally() { lock.unlock(); } } public void out() { lock.lock(); try { while(flag) try{ consumer_con.await(); }catch(InterruptionException e){}; System.out.println(Thread.currentThread().getName()+"...消费者......."+this.name); flag = true; //notifyAll(); //con.notifyAll(); produce_con.signal(); }finally { lock.unlock(); } }}class Producer implements Runnable{ private Resource r; Producer(Resource r) { this.r = r; } public void run() { while(true) { r.set("烤鸭"); } }}class Consumer implements Runnable{ private Resource r; Consumer(Resource r) { this.r = r; } public void run() { while(true) { r.out(); } }}class ProducerConsumerDemo{ public static void main(String[] args) { //创建资源 Resource r = new Resource(); //创建任务 Producer pro = new Producer(r); Consumer con = new Consumer(r); //创建线程,执行任务 Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); Thread t3 = new Thread(con); Thread t4 = new Thread(con); //开启线程 in.start(); out.start(); }}
–wait和sleep的区别
1.wait可以指定时间,也可以不指定,sleep必须指定时间。
2.在同步中时,对CPU的执行权和锁的处理不同。
–wait:释放执行权,释放锁;
–sleep: 释放执行权,不释放锁。
恢复冻结:
–可以使用interrupt()方法将线程从冻结状态强制恢复到运行状态,让线程具备CPU的执行资格。当强制动作执行时会有InterruptedException异常,记得要处理。
一个特殊的线程:守护线程:
当运行守护线程的时候Java虚拟机会自动退出。
多线程的一个方法
join(); 作用是:等待线程终止。
- 多线程-线程间通讯
- 多线程-线程间的通讯
- 多线程_线程间通讯
- 多线程编程之三 线程间通讯
- JAVA 多线程 线程间的通讯
- 【12】多线程_线程间通讯
- JAVA 多线程 线程间的通讯
- 线程通讯,多线程
- IOS 多线程(4) --线程通讯
- java多线程:3、线程通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- Swift 常用方法总结
- 我的博客地址
- SVM支撑向量机详解(一)
- ios-网络的基本概念
- 《剑指offer》牛客网java题解-旋转数组的最小数字
- 多线程-线程间通讯
- 压缩问题--实验吧
- Java的优势
- 母函数详解
- linux初级学习
- 解题报告: Codeforces Round #305 (Div. 2) E.Mike and Foam (莫比乌斯反演)
- getenv等函数的用法
- c语言 数组元素逆序
- 8.12