• 多线程


    (一)生产者消费者问题:

      1.题目:

        采用Java 多线程技术,设计实现一个符合生产者和消费者问题的程序。 对一个对象(枪膛)进行操作,其最大容量是10颗子弹。 生产者线程是一个压入线程,它不断向枪膛中压入子弹;消费者线程是一个射出线程,它不断从枪膛中射出子弹。

      2.分析:

        这是个生产者与消费者问题,也是线程的同步问题, 为了防止执行个线程访问一个资源时出现忙等待,要使用的wait-notify函数,是两个线程交替执行。

      3.解题步骤:

        a.创建一个Factory类,包含Produce()方法和Consume()方法;

        b.创建一个Producer线程,模拟生产子弹;

        c.创建一个Consume线程,模拟消费子弹 ;

        d.创建一个测试类Demo.

      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();
        }
    }
    Factory

      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();
            }
        }
    }
    Producer

      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();
            }
        }
    }
    Consumer

      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();
        }
    }
    Demo
  • 相关阅读:
    爬取毛概题库
    python爬虫抓取豆瓣电影
    青蛙的约会(POJ 1061 同余方程)
    1234: ZJTZYRC筛offer(并查集 )
    A Simple Math Problem(HDU 1757 构造矩阵)
    Number Sequence(HDU 1005 构造矩阵 )
    How many ways??(HDU 2157)
    线性结构上的动态规划
    Codeforces Round #427 (Div. 2)
    Codeforces Round #426 (Div. 2)
  • 原文地址:https://www.cnblogs.com/bug-baba/p/10564498.html
Copyright © 2020-2023  润新知