Java——线程间通信问题
/*
* 等待/唤醒机制
* 设计的方法:
* 1.wait():让线程处于等待状态,被wait的线程会被存储到线程池中。
* 2.notify():唤醒线程池中的一个线程(任意)
* 3.notifyAll():唤醒线程池中的所有线程。
* 这些方法都必须定义在同步中。
* 因为这些方法是用于操作线程状态的方法。必须要明确到底操作的是哪个锁上的线程。********
*
* 为什么操作线程的方法定义在Object中: 因为这些方法都是监视器的方法,监视器其实就是锁。
* 锁可以是任意的对象,任意的对象调用的方式一定定义在Object类中。
*
*
* 生产者和消费者:
*/
class Resrouce
{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String name)
{
while(flag)
{
try
{
this.wait();//让该线程睡着(等待)
}
catch (InterruptedException e)
{
// TODO: handle exception
}
}
this.name = name + count;
count++;
System.out.println(Thread.currentThread().getName()+"....生产者。。。。"+this.name);
flag = true;
/*
* notify唤醒任意一个会出现死锁问题
*/
//notify();//去唤醒一个(睡着的的线程)
//所以唤醒全部
notifyAll();
}
public synchronized void out()
{
while(!flag)
{
try
{
this.wait();//让该线程睡着
}
catch (InterruptedException e)
{
// TODO: handle exception
}
}
System.out.println(Thread.currentThread().getName()+"-----------------消费者-"+ this.name);
flag = false;
/*
* notify唤醒任意一个会出现死锁问题
*/
//notify();//去唤醒一个(睡着的的线程)
//所以唤醒全部
notifyAll();
}
}
//生产者
class Producer implements Runnable
{
private Resrouce r;
Producer(Resrouce r)
{
this.r = r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
while(true)
r.set("馒头");
}
}
//消费者
class Consumer implements Runnable
{
private Resrouce r;
Consumer(Resrouce r)
{
this.r = r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
while(true)
r.out();
}
}
public class ResourceTest
{
/**
* @param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
Resrouce r = new Resrouce();
Consumer c1 = new Consumer(r);
Consumer c2 = new Consumer(r);
Producer p1 = new Producer(r);
Producer p2 = new Producer(r);
Thread t1 = new Thread(p1);
t1.start();
Thread t2 = new Thread(p2);
t2.start();
Thread t3 = new Thread(c1);
t3.start();
Thread t4 = new Thread(c2);
t4.start();
}
}
l
======================================================================
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
* 生产者和消费者:
*
* jdk1.5以后将同步和锁封装成了对象。并将操作锁的隐式方式定义到了该对象中。将隐式动作变成了显示动作。*******************
Lock接口:出现替代了同步代码块或者同步函数,将同步的隐式锁操作变成现实锁操作
lock():获取锁。 通常需要定义在finally代码中。
Condition接口: 出现替代了Object中的wait notify notifyAll方法。
将这些监视器方法单独进行封装,变成Condition监视器对象 可以任意进行组合。
await();
signal();
signalAll();
*/
class Resrouce
{
private String name;
private int count = 1;
private boolean flag = false;
Lock lock = new ReentrantLock();//定义一把锁
//通过已有的锁 获取该锁上的监视器对象。
Condition con = lock.newCondition();
Condition Producer_con = lock.newCondition();//生产者的监视器
Condition Consumer_con = lock.newCondition();//消费者的监视器
public void set(String name)
{
lock.lock();//获取一把锁
try
{
while(flag)
{
try
{
//con.await();
Producer_con.await();//生产者等待 去唤醒一个消费者
}
catch (InterruptedException e)
{
// TODO: handle exception
}
}
this.name = name + count;
count++;
System.out.println(Thread.currentThread().getName()+"....生产者。。。。"+this.name);
flag = true;
//con.signalAll();
Consumer_con.signal();//唤醒消费者
}
catch (Exception e)
{
// TODO: handle exception
}
finally
{
lock.unlock();
}
}
public void out()
{
lock.lock();//获取锁
try
{
while(!flag)
{
try
{
//con.await();
Consumer_con.await();//让消费者等待 然后去唤醒一个生产者。。
}
catch (InterruptedException e)
{
// TODO: handle exception
}
}
System.out.println(Thread.currentThread().getName()+"-----------------消费者-"+ this.name);
flag = false;
//con.signalAll();
Producer_con.signal();//唤醒生产者
}
catch (Exception e)
{
// TODO: handle exception
}
finally
{
lock.unlock();
}
}
}
//生产者
class Producer implements Runnable
{
private Resrouce r;
Producer(Resrouce r)
{
this.r = r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
while(true)
r.set("馒头");
}
}
//消费者
class Consumer implements Runnable
{
private Resrouce r;
Consumer(Resrouce r)
{
this.r = r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
while(true)
r.out();
}
}
public class ResourceTest
{
/**
* @param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
Resrouce r = new Resrouce();
Consumer c1 = new Consumer(r);
Consumer c2 = new Consumer(r);
Producer p1 = new Producer(r);
Producer p2 = new Producer(r);
Thread t1 = new Thread(p1);
t1.start();
Thread t2 = new Thread(p2);
t2.start();
Thread t3 = new Thread(c1);
t3.start();
Thread t4 = new Thread(c2);
t4.start();
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
Java——线程间通信问题的更多相关文章
- Java线程间通信-回调的实现方式
Java线程间通信-回调的实现方式 Java线程间通信是非常复杂的问题的.线程间通信问题本质上是如何将与线程相关的变量或者对象传递给别的线程,从而实现交互. 比如举一个简单例子,有一个多线程的 ...
- Java线程间通信之wait/notify
Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式.我们来看下相关定义: w ...
- java线程间通信:一个小Demo完全搞懂
版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.从一个小Demo说起 上篇我们聊到了Java多线程的同步 ...
- Java——线程间通信
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- 说说Java线程间通信
序言 正文 [一] Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在 ...
- 说说 Java 线程间通信
序言 正文 一.Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在一个 ...
- java线程间通信1--简单实例
线程通信 一.线程间通信的条件 1.两个以上的线程访问同一块内存 2.线程同步,关键字 synchronized 二.线程间通信主要涉及的方法 wait(); ----> 用于阻塞进程 noti ...
- java线程间通信之通过管道进行通信
管道流PipeStream是一种特殊的流,用于在不同线程间直接传送数据,而不需要借助临时文件之类的东西. jdk中提供了四个类来使线程间可以通信: 1)PipedInputStream和PipedOu ...
- Java线程间通信
1.由来 当需要实现有顺序的执行多个线程的时候,就需要进行线程通信来保证 2.实现线程通信的方法 wait()方法: wait()方法:挂起当前线程,并释放共享资源的锁 notify()方法: not ...
随机推荐
- ubuntu安装多个qt版本--不同qt版本编译同一个程序时出现错误--解决方案
方法: 在ubuntu终端: # make clean //有Makefile文件的情况 # rm Makefile *.pro.user # qmake //有多个qt版本,最好指定qmake ...
- JS事件大全
橙色表示“非常常用” 绿色表示“常用” onClick IE3|N2|O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击 onDblClick IE4|N4|O 鼠标双击事件 onMouseD ...
- mybatis写mapper文件注意事项(转)
原文链接:http://wksandy.iteye.com/blog/1443133 xml中某些特殊符号作为内容信息时需要做转义,否则会对文件的合法性和使用造成影响 < < > & ...
- Android模拟器配置选项说明
Memory Options是模拟器的运行内存大小,类比电脑内存大小,就是在设置->应用程序中,正在运行标签页下面显示的那个大小Internal storage是模拟器内置存储空间大小,用于存放 ...
- poj1160 dp
//Accepted 564 KB 63 ms //和hdu1227一样 //dp[i][j]=min(dp[i][j],dp[k][j-1]+cost[k+1][i]) //初始化条件,dp[0][ ...
- JS 基础事件的用法
// 1.9以上用on // 案例一 // $('#btn').on('click', function(){ // //console.log(1); // alert('测试...'); // } ...
- 如何修改svn的密码或重新输入用户名密码
在Eclipse 使用SVN 的过程中大多数人往往习惯把访问SVN 的用户名密码自动保存起来以便下次自动使用,不要再次手工输入,而此时(自动保存密码后),svn又不存在一个显式的登陆框了,但是有些时候 ...
- Java Sudoku游戏
这几天尝试用Java的swing写图形程序,边学习边摸索写了个简单的数独游戏,在编写的过程中学到了不少关于swing的东西,而且对于图形化程序的编写也有了一点简单的认识: 善其事先利其器,既然写图形化 ...
- 深入学习:如何实现不同Android设备之间相同应用程序的网络服务发现功能
在我们的app中添加网络服务发现功能(NSD)以方便在不同的设备上响应局域网中的请求.这种功能对于多设备之间点对点服务来说很有用,例如多人游戏,多人通话,文件共享等. 一,在网络中注册你的服务 注意: ...
- Android屏幕适配常识
屏幕适配的注意事项 1. AndroidManifest.xml设置 在中Menifest中添加子元素 android:anyDensity="true"时,应用程序安装在不同密度 ...