繁体   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