Java同步字符串导致干扰

时间:2018-09-10 22:01:26

标签: java

我正在使用一个简单的程序,其中将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循环,以避免使用颜色对象造成干扰。尽管我将颜色定义为两个线程共享的实例变量,但仍然会产生干扰。 但是,当我使用其他字符串时,它可以正常工作。 我知道可以在此上使用同步,但是我想了解到底发生了什么。

1 个答案:

答案 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块中。

  • 两个胎面都继续并行打印。