虽然我找到了答案,但我遇到了一个我很难理解的问题。请看这个并给我一个答案的解释。
public class TestSeven extends Thread {
private static int x;
public synchronized void doThings() {
int current = x;
current++;
x = current;
}
public void run() {
doThings();
}
}
问题和答案是...... 哪种说法属实?
一个。编译失败。
B中。在运行时抛出异常。
℃。同步run()方法将使类成为线程安全的。
d。变量“x”中的数据可以防止并发访问问题。
电子。 将doThings()方法声明为static将使该类成为线程安全的。
F。将doThings()中的语句包装在synchronized(new Object()){}块中将使该类成为线程安全的。
大胆的一个作为答案。感谢您提前回复!!
答案 0 :(得分:6)
如果你有这样的同步实例方法,它会在实例上进行同步,即每个实例都可以自己访问该方法。但x
是静态的,因此TestSeven
的任何实例都可以同时访问它。
如果doThings()
是静态的,它会在类上同步,因此在给定时间只有一个实例可以访问同步代码。
答案 1 :(得分:1)
以下是将要发生的事情。
public static syncronized void doThings();
这将在类级别同步方法。这意味着只有一个类实例能够在一个实例时访问代码,这意味着其他实例不可能修改静态变量x
。
在其他情况下,
public syncronized void doThings();
这意味着doThings();方法在当前对象上同步。即TestSeven
的实例,因此多个实例可以访问该方法,而该方法又可以改变不希望的静态共享变量x
。
答案 2 :(得分:1)
使方法静态将使其在类级别而不是在实例级别上可用,因此对于此类的所有对象/实例(如静态变量),方法行为将是相同的。因此,类将变为线程安全,因为方法行为不是特定于实例的
答案 3 :(得分:1)
线程安全意味着如果它同时从多个线程使用,则不会导致任何问题。
执行时不使用static
public class TestSeven extends Thread {
private static int x;
public synchronized void doThings() {
int current = x;
current++;
x = current;
}
public void run() {
doThings();
}
}
如果您创建TestSeven
的实例并调用其run()
,则每次都会将输出设为1
。但等待x
是static
所以每次调用时输出都不应该加1?所以这表明该方法不是thread safe
。为了做到这一点,我们会:
使用static
public class TestSeven extends Thread {
private static int x;
public static synchronized void doThings() {
int current = x;
current++;
x = current;
}
public void run() {
doThings();
}
}
记住 synchronized
是让线程安全的“方法”,但还有其他方法。
有关详细信息,请参阅this