Java 多线程线程七扩展线程
我有一个来自OCJP的简单问题 鉴于: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.
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
。您还可以使用withgetAndIncrement()
使其线程安全
<>但是原始形式不是,考虑第二个线程到达第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){
//...
}
}