zoukankan      html  css  js  c++  java
  • 六、多线程基础-多个线程行为不一致/一致共同操作一个数据的设计方法

    1、多个线程行为不一致共同操作一个数据
    如果每个线程执行的代码不同,这时候需要用不同的 Runnable 对象:
    有如下两种方法:
    方法1)将共享数据封装在另外一个对象中,然后将这个对象逐一传递给各个 Runnable 对象。每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据进行的各个操作的互斥和通信。见示列1:ShareDataThreadDifferent

    public class ShareDataThreadDifferent {
        public static void main(String[] args) {
            ShareData1 shareData = new ShareData1();
            for (int i = 0; i < 4; i++) {
                if (i % 2 == 0) {//%是求模运算符   /是除运算符
                    new Thread(new RunnableCusToInc1(shareData), "Thread " + i)
                            .start();
                } else {
                    new Thread(new RunnableCusToDec(shareData), "Thread " + i)
                            .start();
                }
            }
        }
    }
    
    /**
     * 共享数据类
     **/
    class ShareData1 {
        private int num = 10;
    
        public synchronized void inc() {
            num++;
            System.out.println(Thread.currentThread().getName()
                    + ": invoke inc method num =" + num);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public synchronized void dec() {
            num--;
            System.out.println(Thread.currentThread().getName()
                    + ": invoke dec method num =" + num);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    // 封装共享数据类的Runnable类1
    class RunnableCusToInc1 implements Runnable {
        // 封装共享数据
        private ShareData1 shareData;
    
        public RunnableCusToInc1(ShareData1 data) {
            this.shareData = data;
        }
    
        public void run() {
            for (int i = 0; i < 5; i++) {
                shareData.inc();
            }
        }
    }
    
    // 封装共享数据类Runnable类2
    class RunnableCusToDec implements Runnable {
        // 封装共享数据
        private ShareData1 shareData;
    
        public RunnableCusToDec(ShareData1 data) {
            this.shareData = data;
        }
    
        public void run() {
            for (int i = 0; i < 5; i++) {
                shareData.dec();
            }
        }
    }
    View Code

    运行结果:

    Thread 0: invoke inc method num =11
    Thread 0: invoke inc method num =12
    Thread 3: invoke dec method num =11
    Thread 2: invoke inc method num =12
    Thread 1: invoke dec method num =11
    Thread 1: invoke dec method num =10
    Thread 2: invoke inc method num =11
    Thread 2: invoke inc method num =12
    Thread 2: invoke inc method num =13
    Thread 2: invoke inc method num =14
    Thread 3: invoke dec method num =13
    Thread 0: invoke inc method num =14
    Thread 3: invoke dec method num =13
    Thread 3: invoke dec method num =12
    Thread 3: invoke dec method num =11
    Thread 1: invoke dec method num =10
    Thread 1: invoke dec method num =9
    Thread 1: invoke dec method num =8
    Thread 0: invoke inc method num =9
    Thread 0: invoke inc method num =10
    View Code

    方法2)将这些 Runnable 对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable 对象调用外部类的这些方法。见示列1:ShareDataThreadDifferent2

    public class ShareDataThreadDifferent2 {//外部类
        public static void main(String[] args) {
            // 公共数据
            final ShareData2 shareData = new ShareData2();//共享数据类
            for (int i = 0; i < 4; i++) {
                if (i % 2 == 0) {
                    new Thread(new Runnable() {//内部类
                        public void run() {
                            for (int i = 0; i < 5; i++) {
                                shareData.inc();//对共享数据的操作
                            }
                        }
                    }, "Thread " + i).start();
                } else {
                    new Thread(new Runnable() {
                        public void run() {
                            for (int i = 0; i < 5; i++) {
                                shareData.dec();
                            }
                        }
                    }, "Thread " + i).start();
                }
            }
        }
    }
    
    class ShareData2 {
        private int num = 10;
    
        public synchronized void inc() {
            num++;
            System.out.println(Thread.currentThread().getName()
                    + ": invoke inc method num =" + num);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public synchronized void dec() {
            num--;
            System.err.println(Thread.currentThread().getName()
                    + ": invoke dec method num =" + num);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    View Code

    运行结果:

    Thread 0: invoke inc method num =11
    Thread 2: invoke inc method num =12
    Thread 2: invoke inc method num =13
    Thread 3: invoke dec method num =12
    Thread 3: invoke dec method num =11
    Thread 1: invoke dec method num =10
    Thread 1: invoke dec method num =9
    Thread 1: invoke dec method num =8
    Thread 1: invoke dec method num =7
    Thread 1: invoke dec method num =6
    Thread 3: invoke dec method num =5
    Thread 2: invoke inc method num =6
    Thread 0: invoke inc method num =7
    Thread 0: invoke inc method num =8
    Thread 2: invoke inc method num =9
    Thread 3: invoke dec method num =8
    Thread 2: invoke inc method num =9
    Thread 0: invoke inc method num =10
    Thread 3: invoke dec method num =9
    Thread 0: invoke inc method num =10
    View Code

    2、多个线程行为一致共同操作一个数据:
    如果每个线程执行的代码相同,可以使用同一个 Runnable 对象,这个Runnable 对象中有那个共享数据, 例如:买票系统就可以这么做

    public class ShareDataThreadUniformity {
        public static void main(String[] args) {
            ShareData shareData = new ShareData();
            for (int i = 0; i < 4; i++) {
                new Thread(new RunnableCusToInc(shareData),"Thread "+ i).start();
            }
        }
    }
    class ShareData {
        private int num = 10;
        public synchronized void inc() {
            num++;
            System.out.println(Thread.currentThread().getName()
                    + ": invoke inc method num =" + num);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    class RunnableCusToInc implements Runnable {
        private ShareData shareData;
    
        public RunnableCusToInc(ShareData data) {
            this.shareData = data;
        }
    
        public void run() {
            for (int i = 0; i < 5; i++) {
                shareData.inc();
            }
        }
    }
    View Code

    运行结果:

    Thread 0: invoke inc method num =11
    Thread 3: invoke inc method num =12
    Thread 2: invoke inc method num =13
    Thread 2: invoke inc method num =14
    Thread 2: invoke inc method num =15
    Thread 2: invoke inc method num =16
    Thread 2: invoke inc method num =17
    Thread 1: invoke inc method num =18
    Thread 1: invoke inc method num =19
    Thread 1: invoke inc method num =20
    Thread 1: invoke inc method num =21
    Thread 1: invoke inc method num =22
    Thread 3: invoke inc method num =23
    Thread 0: invoke inc method num =24
    Thread 3: invoke inc method num =25
    Thread 3: invoke inc method num =26
    Thread 3: invoke inc method num =27
    Thread 0: invoke inc method num =28
    Thread 0: invoke inc method num =29
    Thread 0: invoke inc method num =30
    View Code
    细水长流,打磨濡染,渐趋极致,才是一个人最好的状态。
  • 相关阅读:
    记录一次nginx的upstream的配置信息
    nginx-1.12.1编译参数详情
    nginx安装ngx_lua_waf防护
    MYSQL增加tmp_table_size 的操作
    windows安装zabbix监控
    mysql 授权
    python基础知识-集合,列表,元组间的相互装换
    python基础知识笔记-集合
    Python基础笔记-元祖
    python基础知识-列表的排序问题
  • 原文地址:https://www.cnblogs.com/jiarui-zjb/p/9622387.html
Copyright © 2011-2022 走看看