Java线程笔记-生产者和消费者

蹲街弑〆低调 提交于 2019-12-04 11:54:55

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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!