首页 > 代码库 > Java——线程间通信问题

Java——线程间通信问题


wait和sleep区别:
1.wait可以指定时间可以不指定。
    sleep必须指定时间。
2.在同步时,对cpu的执行权和锁的处理不同。
    wait:释放执行权,释放锁。
    sleep:释放执行权,不释放锁。

/*

 * 等待/唤醒机制

 * 设计的方法:

 * 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();

}

}

======================================================================


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();

}

}


停止线程的方法: