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
边系鞋带边思考人生.