线程间的通行与等待唤醒机制举例:
一、两个线程:
/**
* @author flame
* @createDate 2012-1-3
* 线程间的通信:
* 首先,有一个资源,提供存取对象
* 一个线程往里面注入资源
* 另一个线程从里面读取资源
* 多个线程操作同一个个数据,不同的是操作动作不同
* 唤醒机制:
* 为避免一个资源注入一般就被另一个资源所读取,所以需要采用唤醒机制。
* 原理:注入时,注入线程执行状态,读取线程等待状态;注入后,注入线程等待状态,读取线程执行状态。
* wait()等待
* notify()唤醒单一线程
* notifyAll()唤醒所有线程
* 唤醒只能唤醒同一个锁的等待线程,不能唤醒不同锁的等待线程,也就是说等待线程的锁和唤醒线程的锁必须同一个。
*/
/**
* 资源,提供姓名和性别
* @author flame
* @createDate 2012-1-3
*/
class Result
{
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name, String sex)
{
if(flag)
try{this.wait();}catch(InterruptedException ex){}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
}
public synchronized void get()
{
if(!flag)
try{this.wait();}catch(InterruptedException ex){}
System.out.println(this.name+"...."+this.sex);
this.flag = false;
this.notify();
}
}
/**
* 注入资源线程
* @author flame
* @createDate 2012-1-3
*/
class InputInfo implements Runnable
{
private Result r; //声明资源类
public InputInfo(Result r) //传入一个资源类,以是得资源为同个资源
{
this.r = r;
}
public void run()
{
int i= 0,j =0;
while(i <=500)
{
if(j == 0)
r.set("flame", "man");
else
r.set("火", "男");
j = (j+1)%2;
i++;
}
}
}
/**
* 获取资源中的数据
* @author flame
* @createDate 2012-1-3
*/
class OutputInfo implements Runnable
{
private Result r;
public OutputInfo(Result r)
{
this.r = r;
}
public void run()
{
int i = 0;
while(i<500)
{
r.get();
i++;
}
}
}
public class communcationThreadDemo {
/**
* 启动线程
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Result r = new Result();
new Thread(new InputInfo(r)).start();
new Thread(new OutputInfo(r)).start();
}
}
二、多线程 (生产者与消费者)
/**
* 生产者与消费者举例
* 当出现多个线程时,唤醒机制的另一种解决方式
* @author flame
* @createDate 2012-1-3
*/
/**
* 资源类
* 初始化资源对象
* 控制资源注入和输出线程
* @author flame
* @createDate 2012-1-3
*/
class Ruselt
{
private String name;
private int count =0;
private boolean flag = false;
public synchronized void set(String name)
{
while(flag)
try{
this.wait();
}catch(InterruptedException ex)
{
System.out.println(ex.getMessage());
}
this.name = name +"***----***"+count++;
System.out.println(Thread.currentThread().getName()+"******生产者******"+this.name);
this.flag = true;
this.notifyAll();
}
public synchronized void get()
{
while(!flag) //此处如果采用if语句判断,会使得当以线程判断通过而放弃资格后,在苏醒时会不再经过判断而继续执行下面的代码
try{
this.wait();
}catch(InterruptedException ex)
{
System.out.println(ex.getMessage());
}
System.out.println(Thread.currentThread().getName()+"=====消费者================="+name);
this.flag = false;
this.notifyAll(); //唤醒所有线程,避免全部线程处于等待状态
}
}
class InputComm implements Runnable
{
private Ruselt r;
public InputComm(Ruselt r)
{
this.r = r;
}
public void run()
{
int i=0;
while(i<500)
{
r.set("商品");
i++;
}
}
}
class OutputComm implements Runnable
{
private Ruselt r;
public OutputComm(Ruselt r)
{
this.r = r;
}
public void run()
{
int i=0;
while(i<500)
{
r.get();
i++;
}
}
}
public class moreThreadDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Ruselt r = new Ruselt();
new Thread(new InputComm(r)).start();
new Thread(new OutputComm(r)).start();
}
}