这里需要同步

时间:2009-12-03 20:06:58

标签: java synchronization multithreading

我有一个java小程序。 applet中的一个类正在创建一个线程来完成一些工作,等待30秒完成该工作,如果它在30秒内没有完成它设置一个布尔值来停止线程。等待和布尔更改是在同步块中,考虑到没有其他线程从这些2开始运行,这是必要的。

    System.out.println("Begin Start Session");
    _sessionThread = new SessionThread();
    _sessionThread.start();

    synchronized (_sessionThread)
    {
        _sessionThread.wait(30000);
        _sessionThread._stopStartSession = true;
    }

为什么我不能这样做呢。

    System.out.println("Begin Start Session");
    _sessionThread = new SessionThread();
    _sessionThread.start();

    _sessionThread.wait(30000);
    _sessionThread._stopStartSession = true;

SessionThread运行方法。调用JNI方法调用dll打开程序窗口。

public void run()
{
    try
    {
        startExtraSession();
    } 
    catch (Throwable t)
    {
        t.printStackTrace();
    }
        notify();
}


private native void openSessionWindow(String session_file);

private void startExtraSession()
{
    final String method_name = "startExtraSession";

    String title = _sessionInfo._title;
    long hwnd = 0;

    openSessionWindow(_sessionInfo._configFile);

    try
    {
        //Look for a window with the predefined title name...
        while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession)
        {
            Thread.sleep(500);
    }
    }
    catch(Throwable t)
    {
       t.printStackTrace();
    }
}

1。真的需要同步吗?
2。除了使用线程之外,还有更好的方法来实现这一点吗?

4 个答案:

答案 0 :(得分:3)

要求给定线程拥有对象的锁定,以便能够在其上调用wait(long)。这是通过在所述对象上使用同步块来实现的。

有关使用wait的信息,请参阅J2SE specification

在java中获取锁定/监视器可以通过多种方式完成:

  • synchronized(非静态)方法中,线程拥有this引用的对象的监视器。
  • static synchronized方法中,线程拥有定义所述方法的类的Class<?>描述符上的监视器。
  • synchronized(x)块中,该主题拥有x上的监视器。

如果出现以下情况,该锁定将被释放:

  • 您不在同步代码块之外(无论是方法,静态方法还是显式块)。
  • 您已调用wait()或其中一个变体(您将在方法返回之前重新获取它)。

这两个列表都可能省略特定情况,但至少应涵盖大部分典型用例。

答案 1 :(得分:1)

您需要synchronized来呼叫wait

这是一个非常简单的原因

synchronized确保在您拨打notify

的同时,没有人在呼叫notifyAllwait

例如:线程1

synchronized( obj )
{
    triggerActionOnThread2();
    obj.wait();
}

线程2(由triggerActionOnThread2触发)

    ...
    synchronized( obj )
    {
        obj.notify();
    }

如果您没有同步块,则notify可能会在wait之前(或期间)发生,然后wait会错过notify,你可以挂起1号线。

想象一下上面没有synchronized块的代码块,想象一下如果在调用wait之前,线程2一直在通知中执行。

顺便说一下,当这项工作涉及多线程编程时,我对Java工程师的采访提出了这个问题。

答案 2 :(得分:0)

您能否发布SessionThread代码?如果你没有锁,你就等不及了,所以你需要synchronized(_sessionThread)来做_sessionThread.wait(30000);不确定_sessionThread._stopStartSession = true;

是什么

答案 3 :(得分:0)

如果布尔值是线程之间唯一的共享状态,则声明布尔瞬态将保证在线程之间看到对它的更改,就像访问布尔值的同步块一样。