2011-04-06 14 views
9

Çalışan bir iş parçacığım var ancak dışarıdan bu iş parçacığını durdurmak için bir değeri atlayamıyorum. Mytest()'un içinde yanlış/gerçek değeri nasıl gönderebilirim veya çalışan genel konuları mı çağırabilirim? Düğmeye1 bastığımda? örn: thread.interrupt();runnable.stop(); veyaÇalışan konuya/çalıştırmaya nasıl erişilir?

// Main 
public class Main extends JFrame 
{ 
    public static Runnable runnable; 
    public static Thread thread; 
    private JButton b1 = new JButton("Start/Stop"); 

    public void init() 
    {  
    //Execute a job on the event-dispatching thread: 
    try { 
     javax.swing.SwingUtilities.invokeAndWait(new Runnable() 
     { 
     public void run() 
     { 
      createGUI(); 
     } 
     }); 
    } catch (Exception e) { 
     System.err.println("createGUI didn't successfully complete"); 
    } 
    } 

    public void createGUI() 
    { 
    Container cp = getContentPane(); 
    b1.addActionListener(new button1()); cp.add(b1); 
    runnable = new Mytest(); 
    thread = new Thread(runnable); 
    thread.start(); 
    } 
} 

// Button 1 - [problem to go inside a running thread] 
public class button1 implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
    System.out.println("button pressed - need to access "); 
     //thread.interrupt();  runnable.stop(); //or runnable.start(); 
    } 
} 

// Running - Thread 
public class Mytest implements Runnable 
{ 
    public static boolean onoff = false; 
    public static boolean status = false; 

    public void run() 
    { 
    while(true) 
    { 
     if (onoff) 
     { 
     return; 
     } else { 
     if (status==false) System.out.println("running"); 
     } 
    } 
    } 
    public static void stop() { status = true; onoff=true; } 
    public static void start() { status = false; onoff = false; } 
} 

runnable.start(); (okuma kanıtı) Takip:

Step 1: 

/* Main - boot/startup */ 
public class Main extends JFrame 
{ 
    public static Mytest runnable; // wrong: public static Runnable runnable; 
    public static Thread thread; 
    private JButton b1 = new JButton("Start"); 
    private JButton b2 = new JButton("Stop"); 

    public void init() 
    {  
    // Execute a job on the event-dispatching thread: 
    // In case Freezed for heavy lifting 
    try { 
     javax.swing.SwingUtilities.invokeAndWait(new Runnable() 
     { 
     public void run() 
     { 
      createGUI(); 
     } 
     }); 
    } catch (Exception e) { 
     System.err.println("createGUI didn't successfully complete"); 
    } 
    } 

    public void createGUI() 
    { 
    Container cp = getContentPane(); 
    b1.addActionListener(new button1()); 
    cp.add(b1); 

    runnable = new Mytest(); 
    thread = new Thread(runnable);  
     try { 
       thread.sleep(100); // value is milliseconds   
       thread.start();  
     } catch (InterruptedException e) {    
     } 
    } 

    public static void main(String[] args) 
    {   
    run(new Main(), 500, 500); 
    } 

    public static void run(JFrame frame, int width, int height) 
    {  ... 
    frame.setVisible(true); 
    } 
} 

/* To start */ 
public class button1 implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
    runnable.start(); 
    }  
} 

/* To stop */ 
public class button2 implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
    runnable.stop(); 
    }  
} 

Step 2: 

/* Thread deals */ 
public class Mytest implements Runnable 
{ 
    private static volatile boolean running = true; 

    public void run() 
    { 
    while(running) 
    { 
     // do stuff 
    } 
    } 
    public void start() { running = true; } 
    public void stop() { running = false;} 
} 

cevap

8

sınıfta tarafından yerine, örnek yöntemleri çağırabilir bir Runnable olarak tanımlarsanız.

public static Mytest runnable; 

Ayrıca çoklu çekirdek kendi ilişkili bellek olan nedeniyle, zaman devlet başka işlemci üzerinde değiştirilebilir işlemci uyarmak zorundayız ve bu değişim için izlemek gerektiğini unutmayın. karmaşık geliyor, ama başlangıçtaki kodda olduğu gibi Runnable başlatın

public class Mytest implements Runnable 
{ 
    private static volatile boolean running = true; 

    public void run() 
    { 
    while(running) { 
     // do stuff 
    } 
    } 

    public void stop() { running = false;} 
} 
sadece boolean bayrakları için 'uçucu' bir anahtar kelime eklemek, daha sonra bu iş parçacığı olduğunu, aslında Apart

+0

, sadece tek döngü stoping edilir? Ama örnek hala kapalı değil mi? Bu kod modelinde mi? Sonra Thread.stop() veya Thread.interrupt() havuzu öldürmek için gerektirir? – YumYumYum

+3

, "run" yöntemi sona erdiğinde thread durur. Gerekirse, Mytest örneğini yeni bir Thread'e ekleyebilir veya tekrar çalıştırmak istiyorsanız mevcut threadda 'start()' diyebilirsiniz. Bu kod sadece çalışan kodun makul bir zaman dilimi içinde tamamlanmasını sağlar (bayrak uçucu değilse durum böyle değildir) –

+0

Teşekkürler! Lütfen yukarıdaki son güncellemeye bakın. Yani demek istediğimiz, bayrağı durdurmak için while döngüsünü işaretlersek, bu iş parçacığı otomatik olarak koparır ve eğer başlatabilirsek() iş parçacığı yaratır mı? – YumYumYum

1

runnable.stop() kullanarak kapatmaya CPU için bir ısıtma testi; Sen başlangıç ​​çağırabilir

)/Senolarak tanımladığınız

MyThread.start(); 
MyThread.stop(); 

ile yöntemlerini durdurmayöntemleri, bu nedenle yukarıdaki kod satırlarında bunları nasıl arayacağınızı gösterir. Isıtma için

... makul bir değere (bir çekirdek üzerine)% 100 CPU yükünü azaltacaktır

try { 
    Thread.sleep(100); // value is milliseconds 
} catch (InterruptedException e) { 
    // no need to handle (in this example) 
} 

Bu gibi bir şey ekleyin; koşunuz yönteminde

2

) .. .

iken (doğru) yapmak yok ..

bir boolean kullanmak ... gibi ... iken (threadIsRunning)

ve doğru/yanlış olarak ayarlayabilirsiniz bu boole ....

+2

Doğru, ama bir 'AtomicBoolean' olması gerekecek çünkü a) son ve b) olması gerekecek, bu da iplik senkronizasyonunun garanti edildiği şekilde –

3
 

public void run() 
    { 
    while(!isInterrupted()) { 
     if (onoff) { 
     return; 
     } else { 
     if (status==false) System.out.println("running"); 
     } 
    } 
    } 

 

Sonra Thread.interrupt() telin bir interrption belirtmek için kullanırlar.

Not: Thread.stop() öğesini hiçbir koşulda kullanmayın! Kullanımdan kaldırıldı!
Daha ayrıntılı bilgi için JDK dokümanı ve < < Java Concurrency Uygulamada >> referans alınabilir.

6

Bir iş parçacığını durdurmak için kesme yöntemini her zaman kullanmalısınız. Bu, güvenli bir işlemdir ve bir durdurma işlemini bir iş parçacığı gerçekleştirmek için yeterli bir yoldur.

Thread tThread = new Thread(new Runnable() { 

       public void run() { 
         while (!Thread.currentThread().isInterrupted()) { 
         try{ 
         Thread.sleep(10); 
         ... do you stuff... 
         }catch(InterruptedException ex){ 

          break; 
         } 
        } 

       } 

      }); 
    tThread.start(); 

Ve size sadece kesme yöntemini çağırmak ipliğe durdurmak istediğinizde: runnable.stop() çağrıldığında

tThread.interrupt(); 
+0

tThread.join(); onu durdurmak için uygun yoldur. Herhangi bir uyku veya işlemin tamamlanmasını bekler, böylece yeniden başlattığınızda yeniden oluşturulabilir. –