有谁能帮我解决以下问题?
public class Starter extends Thread{
private int x=2;
public static void main(String[] args) throws Exception{
new Starter().makeItSo();
}
public Starter(){
x=5;
start();
}
public void makeItSo() throws Exception {
join();
x=x-1;
System.out.println(x);
}
public void run(){x*=2;}
}
一个。 4
B中。 5
℃。 8
d。 9
电子。编译失败
F。在运行时抛出异常
-G。确定某些
是不可能的在转储中答案是D.我知道在新的Starter()。makeItSo中创建了一个新线程。但有人能告诉我为什么run()中的x * = 2在方法makeItSo中的x = x-1和System.out.println(x)之间执行?
答案 0 :(得分:1)
但是有人能告诉我为什么run()中的x * = 2在方法makeItSo
中的x = x-1和System.out.println(x)之间执行
那不是发生了什么。以下是对发布的代码中发生的事情的解释:
1)主线程创建一个Starter类型的新对象,首先将其实例变量x初始化为2(变量初始化),然后(在构造函数中)将相同的实例变量设置为5,然后启动新线程。
2)主线程调用方法makeItSo(在构造函数调用创建的Starter实例上)并加入新线程,等待它完成。
3)新线程执行其run方法,将x加倍,并完成(通知主线程它已完成)。
4)然后主线程被唤醒,从x中减去1,然后打印9。
由于x是跨线程修改的,并且不是易失性的或原子的,并且没有执行同步,因此新线程对x的更新保证对主线程可见是不明显的(因此,无论是故意还是偶然工作都不清楚),使G看起来像是正确的答案。但是join在新线程上执行同步(因为join是使用wait实现的,在线程上锁定);当主线程从连接调用返回时,x的当前值将可见。所以答案是D。