2009-12-03 65 views
0

我有一个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.除了使用线程之外,还有更好的方法来完成这个吗?

回答

3

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

请参阅J2SE specification关于使用wait

获取Java中的锁定/监视器可以以各种方式来完成:

  • 在​​(非静态)的方法,该线程拥有由this引用的对象上的监视器。
  • static synchronized方法中,线程在定义所述方法的类的Class<?>描述符上拥有监视器。
  • synchronized(x)块中,该线程拥有一个显示器x。如果

该锁将被释放:

  • 你得到同步代码块之外(无论是方法,静态方法,或明确的块)。
  • 您已拨打wait()或其中一个变体(您将在方法返回之前重新获取它)。

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

+0

如果线程由班级拥有,他将从中调用同步部分,是否不符合此要求?自从我的Java时代已经很长时间了,所以请赐教。 – 2009-12-03 20:21:31

+0

如果您在任何同步方法或任何同步块之外,则您不拥有任何监视器,因此无法调用“wait”。让我编辑我的答案在锁定/监视器采集上更清晰一些。 – Romain 2009-12-04 08:12:46

0

请问您可以发布SessionThread代码吗?你不能等待,如果你不拥有锁,所以你需要同步(_sessionThread)来做_sessionThread.wait(30000);不知道_sessionThread有什么。_stopStartSession = true;

+0

我猜布尔值杀死了第二个线程中的一个循环。 – 2009-12-03 20:23:56

+0

是的,如果第二个线程运行时间超过30秒,那么当布尔变化时,while将会中断。发布其他代码以及 – Keibosh 2009-12-03 20:45:58

1

有你需要​​调用wait

的​​一个很简单的理由可以确保没有人呼吁的同时notifynotifyAll你打电话wait

例如:线程1

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

线程2(由triggerActionOnThread2触发)

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

如果没有synchronized块,那么notify可能之前(或期间)的wait发生,然后wait错过了notify,你可以挂线程1

想象上面的代码块没有​​块,并想象如果线程2在等待被调用之前一直执行通知。

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

+0

似乎同步是出现异常的明确目的? – 2009-12-04 02:32:42

+0

不完全。同步是为了确保正确的顺序。等待/通知基本上是一个信号量。你想确保一个线程先等待,另一个线程再次通知。 – karoberts 2009-12-04 04:13:58

+0

我的意思是在给出的例子中。但在再次查看之后,notify()是try/catch之后的。感谢您的输入(或者是您的输出?)! – 2009-12-04 13:12:54

0

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