• 多线程-使线程具有有序性


    使线程具有有序性:

    线程在运行时多个线程之间执行的时机是无序的,下面通过改造代码实现运行具有有序性:

     1 /**
     2  *    线程类
     3  */
     4 public class MyThread extends Thread {
     5     private Object lock;
     6     private String showChar;
     7     private int showNumPosition;
     8     private int printCount = 0;//统计打印了几个字母
     9     volatile private static int addNumber = 1;
    10     
    11     //构造
    12     public MyThread(Object lock, String showChar, int showNumPosition) {
    13         this.lock = lock;
    14         this.showChar = showChar;
    15         this.showNumPosition = showNumPosition;
    16     }
    17     
    18     @Override
    19     public void run() {
    20         try {
    21             synchronized(lock) {
    22                 while(true) {
    23                     if(addNumber % 3 == showNumPosition) {
    24                         System.out.println("ThreadName = " + Thread.currentThread().getName() 
    25                                 + " runCount" + addNumber + " " + showChar);
    26                         lock.notifyAll();
    27                         addNumber++;
    28                         printCount++;
    29                         if(printCount == 3) {
    30                             break;
    31                         }
    32                     }else {
    33                         lock.wait();
    34                     }
    35                 }
    36             }
    37         } catch (InterruptedException e) {
    38             e.printStackTrace();
    39         }
    40     }
    41 }
     1 /**
     2  *    测试,线程有序执行打印
     3  */
     4 public class Run {
     5     /**
     6      *    线程执行分析:
     7      *        当三个线程启动后,如果是b和c线程拿到锁,则会进入到else中线程等待
     8      *        printCount为每个线程私有的变量,也就是每个线程都会执行三次后不再循环
     9      *        addNumber为线程共享变量,三个线程分别运行结束之后addNumber累加
    10      *    运行结果如下:
    11      *        ThreadName = Thread-0 runCount1 A
    12      *        ThreadName = Thread-1 runCount2 B
    13      *        ThreadName = Thread-2 runCount3 C
    14      *        ThreadName = Thread-0 runCount4 A
    15      *        ThreadName = Thread-1 runCount5 B
    16      *        ThreadName = Thread-2 runCount6 C
    17      *        ThreadName = Thread-0 runCount7 A
    18      *        ThreadName = Thread-1 runCount8 B
    19      *        ThreadName = Thread-2 runCount9 C
    20      *
    21      *        可以看到第一个运行的是a线程,因为a线程构造参数showNumPosition正好就是初始的addNumber%3的值
    22      *        此时运行代码后输出:ThreadName = Thread-0 runCount1 A
    23      *        全局addNumber修改为2,a线程中的printCount变成1,当A线程再次执行循环时,进入else代码块,线程等待
    24      *        
    25      *        此时如果时线程c拿到锁,则线程c会进入else块,线程等待,然后线程b拿到锁,由于当前线程a修改了全局addNumber,
    26      *        所有线程b在进入循环判断时,构造参数showNumPosition正好就是初始的addNumber%3的值
    27      *        此时运行代码后输出:ThreadName = Thread-1 runCount2 B
    28      *        并唤醒其他线程,此时a和c线程被唤醒,争抢锁
    29      *        全局addNumber修改为3,b线程中的printCount变成1,当c线程再次执行循环时,进入else代码块,线程等待
    30      *        
    31      *        此时如果是a线程获得锁,则会进入else块,线程等待,然后c线程拿到锁,由于当前线程b修改了全局addNumber,
    32      *        所有线程c在进入循环判断时,构造参数showNumPosition正好就是初始的addNumber%3的值
    33      *        此时运行代码后输出:ThreadName = Thread-2 runCount3 C
    34      *        并唤醒其他线程,此时a和b线程被唤醒,争抢锁
    35      *        全局addNumber修改为4,c线程中的printCount变成1,当c线程再次执行循环时,进入else代码块,线程等待
    36      *        
    37      *        以此类推,当线程中的私有变量printCount为3后,线程退出循环。
    38      */
    39     public static void main(String[] args) {
    40         Object lock = new Object();
    41         MyThread a = new MyThread(lock, "A", 1);
    42         MyThread b = new MyThread(lock, "B", 2);
    43         MyThread c = new MyThread(lock, "C", 0);
    44         a.start();
    45         b.start();
    46         c.start();
    47     }
    48 }
  • 相关阅读:
    VS 对话框控件的Tab顺序问题
    基于OpenGL三维软件开发
    OpenGL 中的三维纹理操作
    VC 在桌面上绘制一些图形
    VC/MFC如何添加启动界面
    Cordova or Xamarin 用.net开发IOS和Android程序
    ASP.NET Web API
    软件项目如何选型
    CIO的职责、条件及价值
    Oracle日期周详解IW
  • 原文地址:https://www.cnblogs.com/wang1001/p/9585154.html
Copyright © 2020-2023  润新知