Java 什么是共享状态,发生时的竞争条件?
我不希望多线程同时访问同一个方法。如果我们同时访问一个静态方法会发生什么 比赛条件何时发生 什么是共享状态 如果我错了,请纠正我 我不希望多线程同时访问同一个方法 多个线程访问同一个方法不是问题。只有当多个线程访问相同的状态时,竞争条件才能存在。您的程序中没有共享状态,因此没有竞争条件。并发执行的唯一代码段(除了Java 什么是共享状态,发生时的竞争条件?,java,thread-safety,Java,Thread Safety,我不希望多线程同时访问同一个方法。如果我们同时访问一个静态方法会发生什么 比赛条件何时发生 什么是共享状态 如果我错了,请纠正我 我不希望多线程同时访问同一个方法 多个线程访问同一个方法不是问题。只有当多个线程访问相同的状态时,竞争条件才能存在。您的程序中没有共享状态,因此没有竞争条件。并发执行的唯一代码段(除了run())是: 30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random INFO: Entered Num : 2
run()
)是:
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 2
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 45
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 44
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 43
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 42
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 38
Excepted Value = 47 Returned Value = 47
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 41
Excepted Value = 44 Returned Value = 44
Excepted Value = 46 Returned Value = 46
剥离日志(在每个sane实现中都是线程安全的)、休眠(只影响当前线程)和异常处理,这就是您剩下的:
public static int random(int num){
LOGGER.log(Level.INFO,"Entered Num : {0}",num);
try {
Thread.sleep(5);
} catch (InterruptedException e) {
LOGGER.log(Level.INFO,"Interrupted Exception");
}
return num + 2;
}
不仅num
参数对每个线程都是私有的(每个线程都有自己的堆栈内存),而且它永远不会被修改。因此,您的程序中不会出现竞争条件
代码中没有共享状态(全局变量),只有当一个线程修改共享数据而另一个线程读取数据时,才可能出现争用条件
你想看看比赛情况吗?给你
public static int random(int num){
return num + 2;
}
灾难发生后的最后几秒钟:
random(42)
,分配globalNum=42
,然后进入睡眠状态random(17)
,分配globalNum=17
,然后进入睡眠状态globalNum
(即17
)的当前值,并返回19
,而不是预期的44
这可以是一个静态变量,其中一个线程更改,而另一个线程读取 局部变量不受影响,方法调用也不受影响,因为每个线程都有自己的局部变量
您没有在踏板之间共享的公共资源。您期望的输出是什么,为什么?为什么您认为这会导致比赛状态?@OliCharlesworth,很抱歉这篇文章不连贯。我编辑了我的观点。感谢you@BaptisteWicht,我假设如果多个线程同时访问同一个方法,则会出现争用情况。它错了吗?@bharathi是的,它错了,只有在有共享资源的情况下才会出现竞争条件。访问方法从来都不是问题,问题是在共享资源上并行执行代码。托马斯努尔基维茨的答案解释得很好。
public static int random(int num){
return num + 2;
}
private volatile int globalNum;
public static int random(int num){
globalNum = num;
try {
Thread.sleep(5);
} catch (InterruptedException e) {
LOGGER.log(Level.INFO,"Interrupted Exception");
}
return globalNum + 2;
}