2011-01-04 7 views
1

Es ist ein RMI-Server-Objekt, so dass viele sethumanActivity() ausgeführt werden kann, wie stelle ich sicher, dass der vorherige changeToFalse-Thread gestoppt oder angehalten wird, bevor das neue changeToFalse ausgeführt wird? t. interrupt?Wie starte ich einen Thread?

Grundsätzlich, wenn sethumanActivity() aufgerufen wird, wird die humanActivity auf True festgelegt, aber ein Thread wird ausgeführt, um es auf false zurückzusetzen. Aber ich denke darüber nach, wie man den Thread deaktiviert oder killt, wenn eine andere sethumanActivity() aufgerufen wird?

public class VitaminDEngine implements VitaminD { 

    public boolean humanActivity = false; 
    changeToFalse cf = new changeToFalse(); 
    Thread t = new Thread(cf); 


    private class changeToFalse implements Runnable{ 

     @Override 
     public void run() { 
      try { 
       Thread.sleep(4000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      humanActivity = false; 
     } 

    } 

    @Override 
    public void sethumanActivity() throws RemoteException { 
     // TODO Auto-generated method stub 
     humanActivity = true; 
     t.start(); 
    } 

    public boolean gethumanActivity() throws RemoteException { 
     // TODO Auto-generated method stub 
     return humanActivity; 
    } 

} 

Herausgegeben nach Hilfe SOER

package smartOfficeJava; 

import java.rmi.RemoteException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class VitaminDEngine implements VitaminD { 

    public volatile boolean humanActivity = false; 
    changeToFalse cf = new changeToFalse(); 
    ExecutorService service = Executors.newSingleThreadExecutor(); 


    private class changeToFalse implements Runnable{ 

     @Override 
     public void run() { 
      try { 
       Thread.sleep(4000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      humanActivity = false; 
     } 

    } 

    @Override 
    public synchronized void sethumanActivity() throws RemoteException { 
     humanActivity = true; 
     service.submit(cf); 
    } 

    public synchronized boolean gethumanActivity() throws RemoteException { 
     return humanActivity; 
    } 

} 

Antwort

4

Verwenden Sie einen ExecutorService. Der ExecutorService erstellt einen einzelnen Thread und Sie können Runnables so oft wie gewünscht an sie senden.

ExecutorService service = Executors.newSingleThreadExecutor(); 

Dann im Code

@Override 
public void sethumanActivity() throws RemoteException { 
    // TODO Auto-generated method stub 
    humanActivity = true; 
    service.submit(cf); 
} 

Auch aus Gründen der Korrektheit, sind Sie unsafely Schreiben in den humanActivity Feld. Es besteht die Möglichkeit von veralteten Lesungen. Es gibt viele Artikel, die über Sichtbarkeit sprechen, die Sie auschecken können here.

+0

bearbeitet, ist es schon sicher? – wizztjh

+1

Ja! Die Deklaration von humanActivity volatile stellt jetzt sicher, dass alle Lesevorgänge den aktuellsten Wert anzeigen. –

2

Thread.interrupt() Pausen wartet, Thread.join() wartet auf einen Thread, bevor Sie fortfahren zu beenden.

+0

Also was sollte ich verwenden, um einen Thread neu zu starten, einfach t.run() und ich werde die vorherige verwerfen und eine neue starten? – wizztjh

+2

Es gibt keine Operation "einen Thread neu starten". Sobald ein Thread beendet ist, ist es weg. Sie müssen ein neues beginnen. Alternativ könnten Sie die ursprünglichen Threads unter Verwendung von z.B. http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html –