java 多线程 有序,多线程-使线程具有有序性

使线程具有有序性:

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

/**

* 线程类

*/

public class MyThread extends Thread {

private Object lock;

private String showChar;

private int showNumPosition;

private int printCount = 0;//统计打印了几个字母

volatile private static int addNumber = 1;

//构造

public MyThread(Object lock, String showChar, int showNumPosition) {

this.lock = lock;

this.showChar = showChar;

this.showNumPosition = showNumPosition;

}

@Override

public void run() {

try {

synchronized(lock) {

while(true) {

if(addNumber % 3 == showNumPosition) {

System.out.println("ThreadName = " + Thread.currentThread().getName()

+ " runCount" + addNumber + " " + showChar);

lock.notifyAll();

addNumber++;

printCount++;

if(printCount == 3) {

break;

}

}else {

lock.wait();

}

}

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

/**

* 测试,线程有序执行打印

*/

public class Run {

/**

* 线程执行分析:

* 当三个线程启动后,如果是b和c线程拿到锁,则会进入到else中线程等待

* printCount为每个线程私有的变量,也就是每个线程都会执行三次后不再循环

* addNumber为线程共享变量,三个线程分别运行结束之后addNumber累加

* 运行结果如下:

* ThreadName = Thread-0 runCount1 A

* ThreadName = Thread-1 runCount2 B

* ThreadName = Thread-2 runCount3 C

* ThreadName = Thread-0 runCount4 A

* ThreadName = Thread-1 runCount5 B

* ThreadName = Thread-2 runCount6 C

* ThreadName = Thread-0 runCount7 A

* ThreadName = Thread-1 runCount8 B

* ThreadName = Thread-2 runCount9 C

*

* 可以看到第一个运行的是a线程,因为a线程构造参数showNumPosition正好就是初始的addNumber%3的值

* 此时运行代码后输出:ThreadName = Thread-0 runCount1 A

* 全局addNumber修改为2,a线程中的printCount变成1,当A线程再次执行循环时,进入else代码块,线程等待

*

* 此时如果时线程c拿到锁,则线程c会进入else块,线程等待,然后线程b拿到锁,由于当前线程a修改了全局addNumber,

* 所有线程b在进入循环判断时,构造参数showNumPosition正好就是初始的addNumber%3的值

* 此时运行代码后输出:ThreadName = Thread-1 runCount2 B

* 并唤醒其他线程,此时a和c线程被唤醒,争抢锁

* 全局addNumber修改为3,b线程中的printCount变成1,当c线程再次执行循环时,进入else代码块,线程等待

*

* 此时如果是a线程获得锁,则会进入else块,线程等待,然后c线程拿到锁,由于当前线程b修改了全局addNumber,

* 所有线程c在进入循环判断时,构造参数showNumPosition正好就是初始的addNumber%3的值

* 此时运行代码后输出:ThreadName = Thread-2 runCount3 C

* 并唤醒其他线程,此时a和b线程被唤醒,争抢锁

* 全局addNumber修改为4,c线程中的printCount变成1,当c线程再次执行循环时,进入else代码块,线程等待

*

* 以此类推,当线程中的私有变量printCount为3后,线程退出循环。

*/

public static void main(String[] args) {

Object lock = new Object();

MyThread a = new MyThread(lock, "A", 1);

MyThread b = new MyThread(lock, "B", 2);

MyThread c = new MyThread(lock, "C", 0);

a.start();

b.start();

c.start();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值