//$Id$
import java.util.logging.Level;
import java.util.logging.Logger;
public class ThreadSafe {
public static final Logger LOGGER = Logger.getLogger(ThreadSafe.class.getName());
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;
}
public static void main(String[] args){
for(int threads=1;threads<100;threads++){
final int number = threads;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int val = ThreadSafe.random(number);
System.out.println("Excepted Value = " + (number+2) + " Returned Value = " + val);
}
},"Thread : "+threads);
thread.start();
}
}
}
输出:
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
我除了同时访问同一方法的多线程外。如果我们同时访问静态方法会发生什么?
当竞争状况发生时?
什么是共享状态?
如果我错了,请纠正我。
答案 0 :(得分:3)
同时执行的唯一一段代码(run()
除外)是:
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;
}
剥离日志记录(在每个健全的实现中都是线程安全的),休眠(只影响当前线程)和异常处理,这就是你剩下的:
public static int random(int num){
return num + 2;
}
每个线程不仅num
参数是私有的(每个线程都有自己的堆栈内存),而且它永远不会被修改。因此,您的计划中不会出现竞争条件。
代码中没有共享状态(全局变量),只有当一个线程修改共享数据而其他线程读取它时,才可能出现竞争条件。
你想看到竞争条件?你走了!
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;
}
灾难的最后几秒:
主题1进入random(42)
,分配globalNum = 42
并进入睡眠状态
主题2输入random(17)
,分配globalNum = 17
并进入睡眠状态
线程1唤醒读取当前值globalNum
(17
)并按预期返回19
而不是44
。
答案 1 :(得分:0)
我除了多线程同时访问同一个方法外。
访问相同方法的多个线程不是问题。只有当多个线程访问相同的状态时,才会存在竞争条件。您的计划中没有共享状态,因此没有竞争条件。
答案 2 :(得分:0)
多线程在访问公共资源时变得至关重要 这可以是一个静态变量,一个线程更改而另一个线程读取。
局部变量不受影响,也不受方法调用的影响,因为每个线程都有自己的局部变量。
你没有在踏板之间共享共同的资源。