Java 多线程线程七扩展线程

Java 多线程线程七扩展线程,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我有一个来自OCJP的简单问题 鉴于: 1. public class TestSeven extends Thread { 2. private static int x; 3. public synchronized void doThings() { 4. int current = x; 5. current++; 6. x = current; 7. } 8. public void run() { 9.

我有一个来自OCJP的简单问题

鉴于:

1. public class TestSeven extends Thread {
2.     private static int x;
3.     public synchronized void doThings() {
4.         int current = x;
5.         current++;
6.         x = current;
7.     }
8.     public void run() {
9.         doThings();
10.    }
11. }
哪种说法是正确的

编译失败

B.在运行时引发异常

同步run()方法将使类线程安全

D.变量“x”中的数据受到保护,不会出现并发访问问题

E.将doThings()方法声明为static将使类线程安全

F.将doThings()中的语句包装在一个synchronized(new Object()){}块中可以使类线程安全

答案是选项E

我的问题是:由于方法doThings()已经同步了,它不会使线程安全吗


请为这些主题提供一些好的链接。

否,因为它以非原子方式访问静态字段
x
。您还可以使用with
getAndIncrement()
使其线程安全


<>但是原始形式不是,考虑第二个线程到达第1行,而另一个线程在第3行…其中一个增量将丢失。

问题在于
x
是一个静态变量,因此由所有线程共享。由于所有线程都不是在单个对象上同步的(每个线程都使用
this
作为锁),因此没有任何东西可以阻止两个线程并行执行
doThings()
方法。因此,两个线程可能会并行读取x的值,然后并行地增加它,缺少增量


使
doThings()
静态将使所有线程在单个对象上同步:
TestSeven.class

与对象实例的方法关联的
同步
不关心静态变量,这些变量是类的变量。 实际上,在您的例子中,变异变量是一个
静态的
one:
x

为了同步静态变量,此代码段中最简单的两种方法是将
doThings()
声明为静态(这样它将锁定类本身,而不是对象),或者在
synchronized
块的情况下锁定
TestSeven.class

public synchronized static void doThings() 


不,该方法
doThings()
不是线程安全的,因为它是在
上同步的,此
实例意味着不同的对象将使用它们作为访问它的锁。所以没有同步。如果该方法
doThings()
使用共享锁访问该方法,则该方法完全同步。或者,将其设为类级属性将进行同步。

尽管答案更多地是关于doThings()的同步方法,这是正确的,但特别是静态成员x,“可能”与相应线程对象中的值一起缓存。在x不稳定之前,它不会在所有线程之间真正共享

public void doThings(){
  synchronized(TestSeven.class){
    //...
  }
}