(一)生产者消费者问题:安全
1.题目:多线程
采用Java 多线程技术,设计实现一个符合生产者和消费者问题的程序。 对一个对象(枪膛)进行操做,其最大容量是10颗子弹。 生产者线程是一个压入线程,它不断向枪膛中压入子弹;消费者线程是一个射出线程,它不断从枪膛中射出子弹。ide
2.分析:函数
这是个生产者与消费者问题,也是线程的同步问题, 为了防止执行个线程访问一个资源时出现忙等待,要使用的wait-notify函数,是两个线程交替执行。测试
3.解题步骤:this
a.建立一个Factory类,包含Produce()方法和Consume()方法; spa
b.建立一个Producer线程,模拟生产子弹; 线程
c.建立一个Consume线程,模拟消费子弹 ;设计
d.建立一个测试类Demo.3d
4.画图理解:
5.扩展 - 线程安全问题
(1)线程安全出现的缘由:
a.多线程的环境下;(单线程不会出现安全问题)
b.多个线程拥有资源;
c.对共享资源的操做不是原子性的。(原子性是指一次操做要么执行完,要么不执行)
(2)那么怎么解决线程安全问题呢?
答:使用同步代码块。
格式:
sychronized (对象) {
要同步的代码块(你走我不走,我走你不走)
}
(二)代码体现:
1.建立一个Factory类
public class Factory { String name;//加工厂名字 int MAX_SIZE;//最多加工子弹数目 int size;//当前剩余子弹数 public Factory(String name, int MAX_SIZE) { this.name = name; this.MAX_SIZE = MAX_SIZE; } //使用同步方法,保证线程安全 public synchronized void produce(){ while (size >= MAX_SIZE){ try { //子弹充足,等待消费 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { //加工子弹累了,休息会 Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //生产了一颗子弹 size++; System.out.println("压入了一颗子弹,还剩下" + size + "颗"); //唤醒等待的全部线程 notifyAll(); } //使用同步方法,保证线程安全 public synchronized void consume(){ while (size <= 0){ try { //没有子弹了,等待 wait(); } catch (InterruptedException e) { e.printStackTrace(); } try { Thread.sleep(200);//射出子弹累了,休息会 } catch (InterruptedException e) { e.printStackTrace(); } } //射出了一颗子弹 size--; System.out.println("射出了一颗子弹,还剩下" + size + "颗"); //唤醒等待的全部线程 notifyAll(); } }
2.建立一个Producer类实现Runnable接口
public class Producer implements Runnable { Factory factory; public Producer(Factory factory) { this.factory = factory; } @Override public void run() { //循环生产 while (true){ factory.produce(); } } }
3.建立一个Consume类实现Runnable接口
public class Consumer implements Runnable{ Factory factory; public Consumer(Factory factory) { this.factory = factory; } @Override public void run() { //循环消费 while (true){ factory.consume(); } } }
4.建立一个测试类Demo
public class Demo { public static void main(String[] args) { //建立一个加工厂 Factory factory = new Factory("子弹加工厂",200); //建立一个生产者对象和一个消费者对象 Producer producer = new Producer(factory); Consumer consumer = new Consumer(factory); //建立一个生产者线程和一个消费者线程 Thread t1 = new Thread(producer); Thread t2 = new Thread(consumer); //启动线程 t1.start(); t2.start(); } }