您的位置:首页 > 职场人生

黑马程序员 Java基础学习笔记 线程间同信

2014-03-02 20:27 239 查看
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流!
--------------------------------

线程间通信

其实就是多个线程在操作同一个资源,但是操作的动作不同。(资源对象是唯一的可以用做锁)

等待唤醒机制

wait( );notify( );notifyAll( );都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只用同步才具有锁。

为什么定义这些线程的方法要定义在Object类中呢?

因为这些方法在操作同步中的线程时,都必须标识它们所操作线程只有的锁。只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒。

不可以对不同所中 的线程进行唤醒。也就是说等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。

例子---生产者消费者//多线程间通信--多个生产者和多个消费者

class ProducerConsumerDemo

{

public static void main(String[] args)

{

Resource res=new Resource();

Producer pro=new Producer(res);

Consumer con=new Consumer(res);

Thread t1=new Thread(pro);

Thread t2=new Thread(pro);

Thread t3=new Thread(con);

Thread t4=new Thread(con);

t1.start();

t2.start();

t3.start();

t4.start();

}

}

class Resource

{

private String name;

private int count=1;

private boolean flag=false;

public synchronized void set(String name)

{

while(flag)

try{this.wait();}catch(Exception e){}

this.name=name+"....."+count++;

System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);

flag=true;

this.notifyAll();//全唤醒

}

public synchronized void out()

{

while(!flag)

try{this.wait();}catch(Exception e){}

System.out.println(Thread.currentThread().getName()+"........消费者..."+this.name);

flag=false;

this.notifyAll();//全唤醒

}

}

class Producer implements Runnable

{

private Resource res;

Producer(Resource res)

{

this.res=res;

}

public void run()

{

while(true)

{

res.set("++商品++");

}

}

}

class Consumer implements Runnable

{

private Resource res;

Consumer(Resource res)

{

this.res=res;

}

public void run()

{

while(true)

{

res.out();

}

}

对于多个生产者和消费者 为什么要定义while判断标记。

原因:让唤醒的线程再一次判断标记。

为什么要定义notifyAll( )

因为需要唤醒对方线程。因为notify容易出现只唤醒本方线程的情况,导致程序中所有线程都在等待。

JDK1.5中提供啦多线程升级解决方案。

将同步synchronousd替换成实现Lock操作。将Object中的wait, notify,notifyAll,替换成Condition对象。该对象可以从Lock锁中进行获取。

该示例中,实现了本方只唤醒对方操作。

//多线程间通信--多个生产者和多个消费者JDK5.0升级版

import java.util.concurrent.locks.*;

class ProducerConsumerDemo2

{

public static void main(String[] args)

{

Resource res=new Resource();

Producer pro=new Producer(res);

Consumer con=new Consumer(res);

Thread t1=new Thread(pro);

Thread t2=new Thread(pro);

Thread t3=new Thread(con);

Thread t4=new Thread(con);

t1.start();

t2.start();

t3.start();

t4.start();

}

}

class Resource

{

private String name;

private int count=1;

private boolean flag=false;

private Lock lock=new ReentrantLock();

private Condition condition_pro=lock.newCondition();

private Condition condition_con=lock.newCondition();

public void set(String name)throws InterruptedException

{

lock.lock();

try

{

while(flag)

condition_pro.await();

this.name=name+"....."+count++;

System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);

flag=true;

condition_con.signal();//唤醒对方

}

finally

{

lock.unlock();

}

}

public synchronized void out()throws InterruptedException

{

lock.lock();

try

{

while(!flag)

condition_con.await();

System.out.println(Thread.currentThread().getName()+"........消费者..."+this.name);

flag=false;

condition_pro.signal();//唤醒对方

}

finally

{

lock.unlock();

}

}

}

class Producer implements Runnable

{

private Resource res;

Producer(Resource res)

{

this.res=res;

}

public void run()

{

while(true)

{

try

{

res.set("++商品++");

}

catch (InterruptedException e)

{

}

}

}

}

class Consumer implements Runnable

{

private Resource res;

Consumer(Resource res)

{

this.res=res;

}

public void run()

{

while(true)

{

try

{

res.out();

}

catch (InterruptedException e)

{

}

}

}

}

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流!
--------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: