我正在使用一个简单的程序,其中将2个线程定义为仅从10开始递减计数。我有一个ThreadColor类,只是为了能够以不同的颜色为2个线程着色。 包com.sherif;
public class Main {
public static void main(String[] args) {
Countdown countdown = new Countdown();
CountdownThread t1 = new CountdownThread(countdown);
t1.setName("Thread 1");
t1.start();
CountdownThread t2 = new CountdownThread(countdown);
t2.setName("Thread 2");
t2.start();
}
}
class Countdown {
private int i;
String color;
public void doCountdown() {
switch (Thread.currentThread().getName()) {
case "Thread 1":
color = ThreadColor.ANSI_BLUE;
break;
case "Thread 2":
color = ThreadColor.ANSI_RED;
break;
default:
color = ThreadColor.ANSI_CYAN;
}
synchronized (color) {
for (i = 10; i > 0; i--) {
System.out.println(color + Thread.currentThread().getName() + " i= " + i);
}
}
}
}
class CountdownThread extends Thread {
private Countdown countdown;
public CountdownThread(Countdown countdown) {
this.countdown = countdown;
}
@Override
public void run() {
this.countdown.doCountdown();
}
}
我正在同步向下计数的for循环,以避免使用颜色对象造成干扰。尽管我将颜色定义为两个线程共享的实例变量,但仍然会产生干扰。 但是,当我使用其他字符串时,它可以正常工作。 我知道可以在此上使用同步,但是我想了解到底发生了什么。
答案 0 :(得分:0)
您的color
字段 value 不能仅通过在字段上进行同步来保护,因为更改值的赋值语句不同步。
synchronized
块唯一要做的就是确保两个线程不在块内 内同时运行,并且仅当color
的值指的是同一对象。
即使线程1已经在该块内部,也不会阻止线程2更改color
字段的值。
您的代码的时间轴可能是:
线程1设置了color = ThreadColor.ANSI_BLUE
。
线程1进入块,在ANSI_BLUE
对象上同步,然后开始打印。
线程2集color = ThreadColor.ANSI_RED
。
线程2进入与ANSI_RED
对象同步的块,并开始打印。
如您所见,它们甚至没有在同一个对象上同步,因此两者可以同时位于synchronized
块中。
两个胎面都继续并行打印。