线程间的通讯和生产者和消费者之间的问题
2015-12-24 18:55
495 查看
/* 线程间通信 多个线程在处理同一资源,但是任务却不同。 * */ //资源 class Resource{ String name; String sex; } //输入 class Input implements Runnable{ Resource r; Input(Resource r){ this.r=r; } public void run(){ int x=0; while(true){ synchronized (r) { if(x==0){ r.name="mike"; r.sex="nan"; }else{ r.name="丽丽"; r.sex="女女女女女女女"; } x=(x+1)%2; } } } } //输出 class Output implements Runnable{ Resource r; Output(Resource r){ this.r=r; } public void run() { while(true){ synchronized(r){ System.out.println(r.name+"....."+r.sex); }} } } public class Thread23_1 { 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); //开启线程 t1.start(); t2.start(); } }
多线程(线程间通信-等待唤醒机制)
等待/唤醒机制。
涉及的方法:
1.wait():让线程处于冻结状态,被wait的线程会被存储到线程池中。
2.notify():唤醒线程池中一个线程(任意)
3.notifyAll():唤醒线程池中的所有线程
这些方法都必须定义在同步中。
因为这些方法是用于操作线程状态的方法。
必须要明确到底操作的是哪个锁上的线程。
为什么操作线程的方法wait notify notifyAll定义在了
Object类中的?
因为这些方法是监视器的方法,监视器其实就是锁。
锁可以是任意的对象,任意的对象调用的方式一定定义在Object中。
//资源 class Resource{ String name; String sex; boolean flag=false; } //输入 class Input implements Runnable{ Resource r; Input(Resource r){ this.r=r; } public void run(){ int x=0; while(true){ synchronized (r) { if(r.flag){//真,进入等待 try { r.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(x==0){ r.name="mike"; r.sex="nan"; }else{ r.name="丽丽"; r.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() { while(true){ synchronized(r){ if(!r.flag){ try { r.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(r.name+"....."+r.sex); r.flag=false; r.notify(); }} } } public class Thread24_1 { 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); //开启线程 t1.start(); t2.start(); } }
生产者和消费者
/* 生产者,消费者。 多生产者,多消费者的问题。 if判断标记,只有一次,会导致不该运行的线程运行了,出现了数据错误的情况。 while判断标记,解决了线程获取执行权后,是否要运行。 notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。 notifyAll解决了本方线程一定会唤醒对方线程的问题。 * */ class Resource{ private String name; private int count=1; private boolean flag=false; public synchronized void set(String name){ while(flag){ try { this.wait();//唤醒的线程在这里开始运行 //0 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.name=name+count; count++; System.out.println(Thread.currentThread().getName()+"..生产者.."+this.name); flag=true;//0 烤鸭1 //notifyAll(); notify(); } public synchronized void out(){ while(!flag){ try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"..消费者......."+this.name); flag=false; //notifyAll(); 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(); } } } public class Thread26_1 { public static void main(String[] args) { Resource r=new Resource(); Producer pro=new Producer(r); Consumer con=new Consumer(r); Thread t0=new Thread(pro); Thread t1=new Thread(pro); Thread t2=new Thread(con); Thread t3=new Thread(con); t0.start(); t1.start(); t2.start(); t3.start(); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树