代码之家  ›  专栏  ›  技术社区  ›  Keibosh

这里需要同步吗

  •  0
  • Keibosh  · 技术社区  · 15 年前

    我有一个java小程序。小程序中的一个类正在创建一个线程来执行某些工作,等待30秒以完成该工作,如果它在30秒内没有完成,它将设置一个布尔值来停止该线程。wait和Boolean更改在一个synchronized块中,考虑到除了这两个线程之外没有其他线程在运行,这是必要的。

        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 回复  |  直到 15 年前
        1
  •  3
  •   Romain    15 年前

    给定线程需要拥有对象上的锁才能调用 wait(long) 在上面。这是通过在所述对象上使用同步块来实现的。

    J2SE specification 论使用 wait .

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

    • synchronized (非静态)方法,线程在引用的对象上拥有一个监视器 this .
    • 在一个 static synchronized 方法,则线程在 Class<?>
    • 在一个 synchronized(x) 块中,线程拥有一个监视器 x .

    在以下情况下,该锁将被释放:

    • 你打过电话吗 wait()

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

        2
  •  1
  •   karoberts    15 年前

    有一个非常简单的原因,你需要 synchronized 召唤 wait

    同步的 确保没有人打电话 notify notifyAll 在你打电话的同时 等待

    例如:线程1

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

    线程2(由triggerActionOnThread2触发)

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

    如果没有同步块,则 通知 可能发生在事故发生之前(或期间) ,然后是 等待 通知 ,可以挂线1。

    想象一下上面的代码块没有 同步的

    顺便说一句,当工作涉及多线程编程时,我会在Java工程师的面试中问这个问题。

        3
  •  0
  •   adrian.tarau    15 年前

        4
  •  0
  •   Jeremy Raymond    15 年前

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