这一章节我们再次来讨论一下什么时候使用同步?
1.例子:
package com.ray.ch18;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String[] args) {
EvenChecker.test(new IntGenerator());
}
}
class IntGenerator {
private int index = 0;
private boolean cancle = false;
public void next() {
System.out.println(Thread.currentThread().getName() + "开始操作,index="
+ index);
++index;// 出现竞争条件的地方
Thread.yield();
++index;
System.out.println(Thread.currentThread().getName() + "结束操作,index="
+ index);
}
public int getIndex() {
System.out.println(Thread.currentThread().getName() + "获取返回数,index="
+ index);
return index;
}
public void cancle() {
cancle = true;
}
public boolean isCancle() {
return cancle;
}
}
class EvenChecker implements Runnable {
private IntGenerator generator;
public EvenChecker(IntGenerator generator) {
this.generator = generator;
}
@Override
public void run() {
while (!generator.isCancle()) {
generator.next();
int temp = generator.getIndex();
if (temp % 2 != 0) {
System.out.println("生成奇数");
generator.cancle();
}
}
}
public static void test(IntGenerator generator) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 3; i++) {
executorService.execute(new EvenChecker(generator));
}
executorService.shutdown();
}
}
输出:
pool-1-thread-1开始操作,index=0
pool-1-thread-2开始操作,index=0
pool-1-thread-3开始操作,index=2
pool-1-thread-1结束操作,index=4
pool-1-thread-1获取返回数,index=5
pool-1-thread-3结束操作,index=6
pool-1-thread-3获取返回数,index=6
pool-1-thread-3开始操作,index=6
pool-1-thread-2结束操作,index=5
pool-1-thread-2获取返回数,index=7
生成奇数
pool-1-thread-1开始操作,index=7
pool-1-thread-3结束操作,index=9
pool-1-thread-3获取返回数,index=10
pool-1-thread-1结束操作,index=10
pool-1-thread-1获取返回数,index=10
从输出我们总结了出现的问题:就是共同访问受限资源。
2.回答什么时候使用同步:
当前线程读取某一个被上一个线程修改了的变量,或者当前线程修改某个变量,它接下来被其他线程读取。
就像上面的输出:
当thread-2开始操作index,但是在thread-2结束操作index中间,其实其他线程已经多次的修改index的值
(如果我们把next和get两个方法的顺序调换一下,就会得到第二种情况)
总结:这一章节简单介绍了什么时候使用同步。
这一章节就到这里,谢谢。
-----------------------------------