死锁和线程的通信,生产者和消费者

1 定义: 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,形成线程的死锁

2 过程:例如:主线程利用对象占用了一个同步锁,然后执行sleep方法。如果在sleep过程中没有其他线程进入,则主线程继续执行占用后面的同步锁,不会产生死锁;但如果有其他线程进入,其他线程先占用了后面的同步锁,再去要求第一个同步锁时就产生死锁。

3 Object类中的三个方法:必须放在同步代码块中

wait():当前线程挂起并放弃cpu,同步资源使其他线程可访问并修改共享资源,而当前线程排队等候

notify():唤醒正在排队等待同步资源的线程最高者结束等待。因为是队列是先进先出的,所以可以配合wait方法实现交替打印。

notifyAll():唤醒正在排队等待同步资源的所有线程结束等待

4 释放锁:wait()(执行到此方法,此线程等待,直到其他线程执行notify方法将其唤醒,唤醒后继续执行wait之后的代码

   不释放锁:sleep()(该线程睡眠,仍占据cpu,其他线程进来后也睡眠,只有该线程执行完,cpu才交给别的线程),yield(),suspend()

package lianxi1;

class Client{
    int product;
    public synchronized void addproduct(){
        
             if(product>=20){
                 
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }   
            else{
                product++;
                System.out.println(Thread.currentThread().getName()+"正在生产第"+product+"号产品");
                    }
                 notifyAll();
               
    }
    public synchronized void removeproduct(){
    
        if(product<=0){
            
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else{
            System.out.println(Thread.currentThread().getName()+"正在消费第"+product+"号产品");
            product--;
            notifyAll();
        
        }
        }
}
class Producer implements Runnable{
    Client clerk;

    public Producer(Client clerk) {
        super();
        this.clerk = clerk;
    }

    @Override
    public void run() {
            while(true){
                try {
                    Thread.sleep(120);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                clerk.addproduct();
            }
         }
         
        
    
}
class Consumer implements Runnable{
    Client clerk;
    
    public Consumer(Client clerk) {
        super();
        this.clerk = clerk;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        while(true){
            clerk.removeproduct();
        }
        
    }
    
}
public class TestProConsumer {

    public static void main(String[] args) {
        Client clerk = new Client();
        Producer p1 = new Producer(clerk);//clerk确保是同一把锁
        Consumer c1 = new Consumer(clerk);
        Thread t1 = new Thread(p1);
        Thread t3 = new Thread(p1);
        Thread t2 = new Thread(c1);
        t1.setName("生产者1");
        t3.setName("生产者2");
        t2.setName("消费者1");
        t1.start();
        t2.start();
        t3.start();
    }

}
posted on 2014-12-13 22:02  追梦的小屁孩  阅读(993)  评论(0)    收藏  举报