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 ...
随机推荐
- Xlistview的values下的界面
<!-- 下拉刷新,上拉加载更多 --> <string name="xlistview_header_hint_normal">下拉刷新</s ...
- 测试bug级别定义
致命bug:不能完全满足系统要求,系统停止运行,系统的重要部件无法运行,系统崩溃或者挂起等导致系统不能正常运行. 修改优先级为最高,该级别问题需要立即修改. 1.系统崩溃 2.导致程序重启,死机或非法 ...
- oracle触发器的小例子
实现功能: 插入数据前触发,检查与插入数据几个属性相同的在表中的列将状态改为false,再执行插入. 解决方案: CREATE OR REPLACE TRIGGER tri_insert BEFORE ...
- json_decode 与 json_encode 的区别
1.json_decode对JSON格式的字符串进行编码 2.json_encode对变量进行 JSON 编码 3.unset()是注销定义的变量 4.urlencode()函数原理就是首先把中文字符 ...
- python 中的json解析库
当一个json 数据很大的时候.load起来是很耗时的.python中常见的json解析库有cjson,simplesjson,json, 初步比较了一下, 对于loads来讲 simplejson ...
- openstack 中 log模块分析
1 . 所在模块,一般在openstack/common/log.py,其实最主要的还是调用了python中的logging模块: 入口函数在 def setup(product_name, vers ...
- In p = new Fred(), does the Fred memory “leak” if the Fred constructor throws an exception?
No. If an exception occurs during the Fred constructor of p = new Fred(), the C++ language guarantee ...
- php中数据库的操作
1.Mysql客户端介绍,命令行:这种方法不友好. 2.Mysql客户端介绍,Web形式的可视化界面(phpMyAdmin) 优点:只要有浏览器就可以操作数据库 缺点: a)创建数据库
- Juniper SRX防火墙-NAT学习笔记!
Junos NAT第一部分:SRX NAT介绍第二部分:Source NAT:Interface NAT第三部分:Source NAT:Address Pools第四部分:Destination NA ...
- 使用java理解程序逻辑,变量
数据类型 说明 举例 int 整型 用于存储整数.例如.学员人数.某公司的员工编号.一年的天数.一天的小时数 double 双精度浮点型 用于存储带有小数的数字.例如商品的价格.世界的价格.世界银行给 ...