簡體   English   中英

中斷線程Java的更好方法

[英]better way to interrupt thread Java

我已經用Java編寫了一個類:

public class Main {
    public static boolean firstRunning = true;
    public static void main(String[] args) {
        (new Thread(){
            public void run(){
                secondFunction();
            }
        }).start();
        firstFunction();
    }

    public static void firstFunction()
    {
        for(int i = 0; i < 10 && firstRunning; i++)
        {
            try{Thread.sleep(1000);} catch(Exception e){}
            System.out.println("first - "+i);
        }
        return;
    }

    public static void secondFunction(){
        try{Thread.sleep(3000);} catch(Exception e){}
        firstRunning = false;
        for(int i = 0; i < 10; i++)
        {
            try{Thread.sleep(700);} catch(Exception e){}
            System.out.println("second - "+i);
        }
    }
}

我在新線程中調用secondFuntion()之后,開始在Main Thread執行firstFuntion() secondFuntion()執行Thread.sleep(3000)之后,我想讓secondFunction()接管Main Thread ,為此,我將布爾標志firstRunning設置為false,並使用取消了Main Thread的執行。返回聲明。

這種方法對我有用,但是有沒有更優雅的方法呢?

編輯

代碼的輸出是

first - 0
first - 1
first - 2
second - 0
second - 1
second - 2
second - 3
second - 4
second - 5
second - 6
second - 7
second - 8
second - 9

如果只想退出主線程,那么這是最簡單的方法。

但是通常,您有更復雜/不同的需求。 我的猜測是您嘗試解決另一個問題,這是您的第一個解決方案。 除非您告訴我們您最初的問題,否則我們不會告訴您什么是好的解決方案。

如果只希望2個線程共享某些內容(即不同時使用它),則可以使用鎖(請參閱Java 7文檔 )。

偽代碼:

  • 主線程創建鎖
  • 主線程創建第二個線程並將鎖傳遞給它
  • 第一個函數嘗試獲取循環內部的鎖。 成功時,它將運行循環主體一次並釋放鎖。
  • 然后線程2使用該鎖來確保主線程在其工作時處於阻塞狀態

我認為沒有必要積極等待。 一種更優雅的方法是針對此特定問題使用CountDownLatch。 如果希望主線程等待另一個線程執行操作,則可以使用CountDownLatch這樣的示例:

public class Main {
   private static final CountDownLatch latch = new CountDownLatch(1);
   public static void main(String[] args) throws InterruptedException {
       (new Thread(){
           public void run(){
               secondFunction();
           }
       }).start();
       firstFunction();
       System.out.println("DONE!");
   }

    public static void secondFunction(){
        latch.await(); // blocks the main thread here until 
                       // the latch has been counted down to 0
    }

   public static void secondFunction(){
       System.out.println("secondFunction 1");
       try{Thread.sleep(3000);} catch(Exception e){}
       System.out.println("secondFunction 2");
       latch.countDown(); // this counts down the latch from 1 to 0 and
                          // releases the initial thread from blocking
       // ... continue with some other operations
   }

輸出:

secondFunction 1
secondFunction 2
DONE!

請查看Java文檔以獲取更多詳細信息。 解決此方法和解決Java中線程等待問題的“標准”方法的替代方法是使用同步/等待/通知的所謂“監視”概念。 請查看此stackoverflow帖子作為示例。

由於您的實際問題尚不清楚,因此,僅使用以下代碼即可實現輸出。 它使用Java中線程提供的同步,等待/通知功能:

public class Main {
    private static Thread t1;
    private static Object lock = new Object();//dummy object to perform sychronization
    public static void main(String[] args) {
        t1 = new Thread(){
            public void run(){
                secondFunction();
            }
        };
        t1.start();
        firstFunction();
    }

    public static void firstFunction()
    {
        for(int i = 0; i < 10; i++)
        {
            if(i == 3){
                 synchronized (lock) { // wait till the lock is available 
                    try {
                        lock.wait(); // wait till some thread notifies
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            try{Thread.sleep(1000);} catch(Exception e){}
            System.out.println("first - "+i);
        }
        return;
    }

    public static void secondFunction(){
        try{Thread.sleep(3000);} catch(Exception e){} //wait for 3 sec to run the main thread 3 times
        synchronized (lock) { //aquire the lock
             for(int i = 0; i < 10; i++)
             {
                 try{Thread.sleep(700);} catch(Exception e){}
                 System.out.println("second - "+i);
             }
               //don't notify the main thread that this thread is done with lock
        }
    }
}

由於代碼沒有通過第二個功能和新線程通知“鎖”已不再使用,因此主線程將繼續等待通知。

輸出與有問題的相同。

警告:這不是使用鎖定和同步的好方法,而只是為您提供如何使用線程鎖定/同步的示例。 如果您的實際問題明確了,我們將為您確定最佳解決方案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM