-2
    //$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

我排除了同时访问同一方法的多线程。如果我们同时访问一个静态方法会发生什么?

什么时候出现竞态条件?

什么是共享状态?

如果我错了,请纠正我。

4

3 回答 3

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. 线程1进入random(42),分配globalNum = 42并进入睡眠状态

  2. 线程2进入random(17),分配globalNum = 17并进入睡眠

  3. 线程 1 唤醒读取globalNum(which is 17) 的当前值并返回19而不是44按预期返回。

也可以看看

于 2013-01-30T18:25:03.960 回答
0

我排除了同时访问同一方法的多线程。

多个线程访问同一个方法不是问题。只有当多个线程访问相同的状态时,才会存在竞争条件。您的程序中没有共享状态,因此没有竞争条件。

于 2013-01-30T18:24:37.417 回答
0

多线程在访问公共资源时变得至关重要。
这可以是一个静态变量,一个线程更改而另一个线程读取。

局部变量不受影响,方法调用也不受影响,因为每个线程都有自己的局部变量。

您没有在踏板之间共享的公共资源。

于 2013-01-30T18:28:07.197 回答