zoukankan      html  css  js  c++  java
  • java线程之间通信,多种方式实现生产者消费者模式

    java多线程之间的通信,及使用多种方式实现生产者消费者模式

    实现需求:两个线程交替打印1,0,打印10轮

    java多线程口诀:

    1. 高内聚,低耦合
    2. 线程操作资源类
    3. 判断干活通知
    4. 防止虚假唤醒

    方式一:使用synchronized和Object的wait和notifyAll方法

    wait:使当前线程阻塞

    notify,notifyAll唤醒当前线程

    /**
     * 两个线程交替打印1,0 打印10轮
     * 
     * @author Administrator
     * @version 1.0 2020年7月12日
     * @see ProdConsumerDemo1
     * @since 1.0
     * 
     */
    class ShareData1 {
    
        public int number = 0;
    
        public synchronized void increment() throws Exception {
            while (number != 0) {
                this.wait();
            }
            number++;
            System.out.println(Thread.currentThread().getName() + " " + number);
            this.notifyAll();
        }
    
        public synchronized void decrement() throws InterruptedException {
            while (number != 1) {
                this.wait();
            }
            number--;
            System.out.println(Thread.currentThread().getName() + " " + number);
            this.notifyAll();
        }
    }
    
    public class ProdConsumerDemo1 {
    
        public static void main(String[] args) {
            ShareData1 shareData = new ShareData1();
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    try {
                        shareData.increment();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }, "A").start();
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    try {
                        shareData.decrement();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }, "B").start();
        }
    }
    

      

    输出结果

    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0

    方式二:使用jdk1.8的Lock和Condition

    class ShareData2 {
    
        private int number = 0;
    
        private Lock lock = new ReentrantLock();
    
        private Condition condition = lock.newCondition();
    
        public void increment() throws Exception {
            lock.lock();
            try {
                while (number != 0) {
                    condition.await();
                }
                number++;
                System.out.println(Thread.currentThread().getName() + " " + number);
                condition.signalAll();
            } finally {
                lock.unlock();
            }
        }
    
        public void decrement() throws InterruptedException {
            lock.lock();
            try {
                while (number != 1) {
                    condition.await();
                }
                number--;
                System.out.println(Thread.currentThread().getName() + " " + number);
                condition.signalAll();
            } finally {
                // TODO: handle finally clause
                lock.unlock();
            }
        }
    }
    
    public class ProdConsumerDemo2 {
    
        public static void main(String[] args) {
            ShareData2 shareData = new ShareData2();
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    try {
                        shareData.increment();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }, "A").start();
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    try {
                        shareData.decrement();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }, "B").start();
        }
    }
    

      

    输出结果

    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0
    A 1
    B 0

    主要是熟悉Lock和Condition的使用

    Lock和Condition相比于synchronized,能够精确唤醒

    需求:三个线程A,B,C顺序打印,A打印5次,B打印10次,C打印15次,10轮

    class ShareData3 {
    
        private int number = 1;
    
        private Lock lock = new ReentrantLock();
    
        private Condition c1 = lock.newCondition();
    
        private Condition c2 = lock.newCondition();
    
        private Condition c3 = lock.newCondition();
    
        public void print5() throws Exception {
            lock.lock();
            try {
                while (number != 1) {
                    c1.await();
                }
                number = 2;
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                }
                c2.signalAll();
            } finally {
                // TODO: handle finally clause
                lock.unlock();
            }
        }
    
        public void print10() throws InterruptedException {
            lock.lock();
            try {
                while (number != 2) {
                    c2.await();
                }
                number=3;
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                }
                c3.signalAll();
            } finally {
                // TODO: handle finally clause
                lock.unlock();
            }
        }
    
        public void print15() throws InterruptedException {
            lock.lock();
            try {
                while (number != 3) {
                    c3.await();
                }
                number = 1;
                for (int i = 0; i < 15; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                }
                c1.signalAll();
            } finally {
                // TODO: handle finally clause
                lock.unlock();
            }
        }
    }
    
    public class ProdConsumerDemo3 {
    
        public static void main(String[] args) {
            ShareData3 shareData3 = new ShareData3();
            new Thread(() -> {
                try {
                    for (int i = 0; i < 10; i++) {
                        shareData3.print5();
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }, "A").start();
            new Thread(() -> {
                try {
                    for (int i = 0; i < 10; i++) {
                        shareData3.print10();
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }, "B").start();
            new Thread(() -> {
                try {
                    for (int i = 0; i < 10; i++) {
                        shareData3.print15();
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }, "C").start();
        }
    }
    

      

  • 相关阅读:
    CSRF跨站请求伪造
    FineReport 导出汉字乱码
    Java 程序中中文没有乱码,存入数据库后中文乱码问题
    分析函数
    Redis的持久化与主从复制
    分布式Redis的使用
    redis的介绍和安装
    Solr后台管理及SolrJ的使用
    Solr总结
    bootstrap 点击回到顶部 超简单
  • 原文地址:https://www.cnblogs.com/lt123/p/13290098.html
Copyright © 2011-2022 走看看