zoukankan      html  css  js  c++  java
  • 死锁和线程的通信,生产者和消费者

    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();
        }
    
    }
  • 相关阅读:
    django_视图层_便捷工具
    django_视图层_编写url
    04bootstrap_表单
    人工智能之线性代数
    人工智能之数组操作
    C 获取Linux系统信息
    RPM
    Windows 启动&关闭Hyper-V
    C 指定初始化器
    指针的运算
  • 原文地址:https://www.cnblogs.com/yjtm53/p/4161928.html
Copyright © 2011-2022 走看看