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 ...
随机推荐
- IOS多线程之NSOperation学习总结
NSOperation简介 1.NSOperation的作用 配合使用NSOperation和NSOperationQueue也能实现多线程编程 2.NSOperation和NSOperationQu ...
- Android-LogCat日志工具(二)
既然是Java语言,那么对于很多人来说,用System.out.println() 方法来打印日志是最熟悉.最简单不过了.不过在真正的项目开发中,是极度不建议使用 System.out.println ...
- MySQL语句45道练习题及答案
一. 设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表(一)~表( ...
- iOS 三种录制视频方式
随着每一代 iPhone 处理能力和相机硬件配置的提高,使用它来捕获视频也变得更加有意思.它们小巧,轻便,低调,而且与专业摄像机之间的差距已经变得非常小,小到在某些情况下,iPhone 可以真正替代它 ...
- Note_Master-Detail Application(iOS template)_04_ YJYMasterViewController.h
//YJYMasterViewController.h #import <UIKit/UIKit.h> @classYJYDetailViewController; #import < ...
- 2016 - 1 -17 GCD主队列与全局队列
一:主队列 1.概念:每一个应用程序对应唯一一个主队列,直接GET即可:在多线程开发中,使用主队列更新UI dispatch_queue_t q = dispatch_get_main_queue() ...
- UNICODE字符集(20140520)
1多字节字符集,如"IT学吧",sizeof内存长度为7,因为前面2个字母各占用一个字节,后面两个汉字各占用2个字节,结尾的\0占用一个字节.strlen即字符串长度的结果为6. ...
- Spring MVC配置文件解释
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- iOS开发之拖动图片
步骤:1.首先创建一个single view application 2.然后添加一个新的cocoa touch class的类 3.添加的类遵守<UIGestureRecognizerDele ...
- "This connection is untrusted" - Firefox error message
Error Messages I am receiving the following error message in Firefox: After selecting Cancel to clos ...