线程和同步问题

时间:2013-11-30 00:04:31

标签: java multithreading

在某些情况下,以下程序实际上会停止(因为线程2),而不应该停止。为什么会这样?

线程1:基本上锁定global并执行while循环 线程2:尝试锁定global并成功锁定,继续停止程序。

但是首先启动线程1,因此技术上线程2永远不会被调用,因此程序永远不会退出。

static Integer global = 30;

public static synchronized void setVar(int x, String from)
{
    System.out.println(global + " " + x + " - " + from);
    global = x;
}
public static void main(String [] args)
{
    Thread thr1 = new Thread(new Runnable()
    {
        @Override
        public void run() 
        {
            synchronized(global)
            {
                while(true)
                {
                    setVar((int) (Math.random() * 30), "Thread 1");
                }
            }
        }

    });

    Thread thr2 = new Thread(new Runnable()
    {
        @Override
        public void run() 
        {   
            synchronized(global)
            {
                setVar((int) (Math.random() * 30), "Thread 2");
                System.exit(0);
            }
        }

    });

    thr1.start();
    thr2.start();
}

输出(我偶尔得到)

  

30 19 - 线程2

2 个答案:

答案 0 :(得分:4)

thr1完全可以在点击synchronized之前启动并停放 - 然后thr2获取锁定并退出。

我唯一关心的是(int) (Math.random() * 30)如何评估19。现在 很奇怪。

答案 1 :(得分:1)

所有线程相关问题的90%的第1引号:未定义线程执行的顺序。

在你的例子中:

Thread 1: created, put on hold for whatever reason
Thread 2: created, runs to synchronized and gets lock.
Thread 1: resumed, runs to synchronized, has to wait.

因此,如果您编写使用此类同步模型的线程代码,则需要为所有案例做好准备,因为实际发生的是哪一个,没有人可以说。

此外,你的“永远不应该被召唤”。是的,这是不太可能的,但即使机会是1%,这仍然意味着在100次运行中它将至少在统计上发生一次。