zoukankan      html  css  js  c++  java
  • Java线程笔记-生产者和消费者

    Java线程笔记

    1. 线程的介绍:

      Java中每一个对象都可以作为锁,这是synchronized实现同步的基础;

    • 普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁;
    • 静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁;
    • 同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁;

    2. synchronized 关键字;

      关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块;用于解决多线程共同操作共享数据的问题。

    3. 方法介绍;

    • wait() :当前线程进入等待状态,释放锁,停止执行wait() 方法后面的语句;
    • notify() : 
    • notifyAll() : 通知所有等待相同资源的线程,不会立即释放锁,当前线程执行完后释放锁,即,notifyAll()通知发出后,需当前线程执行完后释放锁,其他等待的线程才能抢到资源;

    4. 生产者-消费者实现方式一 (synchronized、wait和notify)

    4.1 先定义一个资源池,用于存放线程共享资源,并提供生产、消费资源的方法

     1 //定义一个资源池的类Resource
     2 
     3 class Resource {
     4     private int num = 0;
     5     private int size = 10;
     6 
     7     // 从资源池中取资源
     8     public synchronized void remove() {
     9         if (num > 0) {
    10             num--;
    11             System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前线程池有" + num + "个");
    12             //当前同步语句块执行完前不释放锁,继续执行完后释放锁,所以通知唤醒等待的线程后,其他线程不能立即执行;
    13             notifyAll(); 
    14         } else {
    15             try {
    16                 System.out.println("消费者" + Thread.currentThread().getName() + "线程进入开始[进入]等待状态");
    17                 //wait释放锁,停止继续执行直到被唤醒才继续往下执行
    18                 //如果没有资源,则消费者进入等待状态
    19                 wait(); 
    20                 System.out.println("消费者" + Thread.currentThread().getName() + "线程[结束]等待状态");
    21             } catch (InterruptedException e) {
    22                 // TODO Auto-generated catch block
    23                 e.printStackTrace();
    24             }
    25         }
    26     }
    27 
    28     // 往资源池中添加资源
    29     public synchronized void add() {
    30         if (num < size) {
    31             num++;
    32             System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个");
    33             // 通知所有正在等待队列中等待同一共享资源的 “全部线程” 退出等待队列,进入可运行状态
    34             //notify不释放锁,必须执行完notify()方法所在的synchronized代码块后才释放
    35             notifyAll(); 
    36             try {
    37                 Thread.sleep(5000);
    38             } catch (InterruptedException e) {
    39                 // TODO Auto-generated catch block
    40                 e.printStackTrace();
    41             }
    42         } else {
    43             try {
    44                 wait();// 当前线程的生产者进入等待状态,并释放锁
    45                 System.out.println(Thread.currentThread().getName() + "线程进入等待");
    46             } catch (InterruptedException e) {
    47                 // TODO Auto-generated catch block
    48                 e.printStackTrace();
    49             }
    50 
    51         }
    52     }
    53 }

    4.2 定义生产者

    //定义生产者线程
    
    /*
     * 生产者线程
     */
    class ProducerThread extends Thread {
        private Resource resource;
    
        public ProducerThread(Resource resource) {
            super();
            this.resource = resource;
        }
    
        public void run() {
            // 不断地生产资源
            while (true) {
                try {
                    Thread.sleep(8000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                resource.add();
            }
        }
    }

    4.3 定义消费者

    //定义消费者线程
    
    /*
     * 消费者线程
     */
    class ConsumerThread extends Thread {
        private Resource resource;
    
        public ConsumerThread(Resource resource) {
            super();
            this.resource = resource;
        }
    
        public void run() {
            while (true) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                resource.remove();
            }
        }
    }

    4.4 定义测试主类

     1 public class ProducerConsumerWithWaitNofity {
     2 
     3     public static void main(String[] args) {
     4         // TODO Auto-generated method stub
     5         Resource resource = new Resource();
     6         //生产者线程
     7         ProducerThread p1 = new ProducerThread(resource);
     8 //        ProducerThread p2 = new ProducerThread(resource);
     9 //        ProducerThread p3 = new ProducerThread(resource);
    10         
    11         //消费者线程
    12         ConsumerThread c1 = new ConsumerThread(resource);
    13         ConsumerThread c2 = new ConsumerThread(resource);
    14         
    15         p1.start();
    16 //        p2.start();
    17 //        p3.start();
    18         c1.start();
    19         c2.start();
    20     }
    21 
    22 }

    备注:代码案例转载自:https://www.cnblogs.com/xiaowenboke/p/10469125.html

  • 相关阅读:
    注册表清理bat
    apache2.2.14 负载均衡过程中遇到问题记录;
    thikpad 中eclipse/idea 无法获取鼠标
    PLSQL DEVELOPER 提示(错误)信息是乱码;亲测有效
    windows右键 打开方式 浏览 无法添加默认打开方式 解决
    澳洲值得代购物品汇总
    5 open source dashboard tools for visualizing data
    nginx概述
    Linux bash 参数处理办法
    Linux shell 启动配置文件设置
  • 原文地址:https://www.cnblogs.com/crazytrip/p/11861765.html
Copyright © 2011-2022 走看看