中断Java线程的更好方法

中断Java线程的更好方法,java,multithreading,Java,Multithreading,我用Java编写了一个类: public class Main { public static boolean firstRunning = true; public static void main(String[] args) { (new Thread(){ public void run(){ secondFunction(); } }).start();

我用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);
        }
    }
}

如果您只想让主线程退出,那么这是最简单的方法

但通常情况下,您有更复杂/不同的需求。我的猜测是,你试图解决一个不同的问题,这是你的第一个解决方案。除非你告诉我们你最初的问题,否则我们无法告诉你什么是好的解决方案

如果您只希望两个线程共享某些内容,即不同时使用它,则可以使用锁,请参见

伪代码:

主线程创建锁 主线程创建第二个线程并将锁传递给它 第一个函数尝试获取循环内部的锁。成功后,将运行循环体一次并释放锁。 线程2然后使用锁来确保主线程在工作时阻塞
我认为没有必要积极等待。一种更优雅的方法是对这个特定问题使用倒计时锁存器。如果希望主线程等待其他线程执行操作,例如,可以使用如下倒计时闩锁:

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!

有关更多详细信息,请查看。使用synchronize/wait/notify的所谓监视器概念是解决Java中线程等待问题的另一种方法和标准方法。请看一个例子。

由于您真正的问题并不清楚,因此为了实现您的输出,您可以使用以下代码。它使用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
        }
    }
}
由于代码没有通过第二个函数和新线程通知锁不再使用,主线程将继续等待通知

输出与讨论中给出的相同


警告:这不是使用锁定和同步的好方法,只是给您一个如何使用线程锁定/同步的示例。如果你真正的问题清楚的话,我们会决定最好的解决方法的。CocoNess,你能告诉我怎么做,或者给我指一个指南吗?我是线程编程新手。谢谢:firstRunning需要易失性,否则上面的代码可能无法按预期工作。我读到了什么是易失性,我会记住这一点。谢谢@Aarondigula@Aarondigula-即使有易变性,他仍然可以以比赛状态结束,对吗?。我的意思是,产出仍然可能变化。同步对变量的访问不是更好吗?@TheLostMind:他没有说他想要这个输出,即main必须在允许第二个线程启动之前完成。我没有更复杂的需要。我在修改一些代码来了解它是如何工作的。谢谢:请注意,使用您的方法,第二个线程可以在第一个线程仍在循环中时开始工作。所以你可以得到输出。。。第二个0第一个2。。。
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
        }
    }
}