【问题标题】:Stop threads and re-running them停止线程并重新运行它们
【发布时间】:2017-10-16 18:11:18
【问题描述】:

我有这个 Java 程序(用于与另一台主机进行音频通信),它以 2 个对象的实例化(即 Thread 类的 2 个扩展)开始。 在某个时间我需要重新启动程序:我怎样才能停止这个线程并重新启动它? Thread.stop 方法已弃用。

public static void main(String[] args){

            Receiver rx = new Receiver();
            Transmitter tx =new Transmitter();
            rx.start();
            tx.start();
}

【问题讨论】:

  • 中断是一种方法,将该标志设置为true是一种方法。毒丸/挥发物是另一种忙碌的旋转。你只需要谷歌他们。
  • 你不应该这样做。不推荐使用 Thread.stop 是有原因的。你甚至不应该处理像 Thread 这样的低级类。查看 java.util.concurrency 包。
  • 您的音频传输是否使用阻塞 I/O?
  • 是的@NathanHughes,我在这些扩展线程中有while循环。

标签: java multithreading restart reboot


【解决方案1】:

下面的 sn-p 是实现您需要的起点。

public class MyThread implements Runnable, Comparable<MyThread> {

    private static volatile int idCount;

    private volatile int id;
    private volatile boolean running;

    public MyThread() {
        id = idCount++;
    }

    @Override
    public void run() {

        running = true;

        while ( running ) {
            System.out.printf( "Thread %d is running!\n", id );
            try {
                Thread.sleep( 1000 );
            } catch ( InterruptedException exc ) {
                exc.printStackTrace();
            }
        }
    }

    public void stop() {
        this.running = false;
    }

    public boolean isRunning() {
        return running;
    }

    public int getId() {
        return id;
    }

    @Override
    public int compareTo( MyThread o ) {
        return this.id - o.id;
    }
}

public class TestMyThread {

    public static void main( String[] args ) {

        Scanner scan = new Scanner( System.in );
        ExecutorService es = Executors.newCachedThreadPool();
        Map<Integer, MyThread> myThreads = new ConcurrentSkipListMap<>();

        int opt = 0;
        int threadToRemoveId = 0;

        while ( opt != 3 ) {

            System.out.println( "1 - Create and start a thread." );
            System.out.println( "2 - Stops a thread." );
            System.out.println( "3 - Finish all threads." );
            System.out.println( "Choose an option: " );
            opt = scan.nextInt();

            switch ( opt ) {

                case 1:

                    MyThread newThread = new MyThread();
                    myThreads.put( newThread.getId(), newThread );
                    es.execute( newThread );

                    break;

                case 2:

                    System.out.println( "What thread should be removed? " );
                    threadToRemoveId = scan.nextInt();

                    MyThread threadToRemove = myThreads.remove( threadToRemoveId );
                    if ( threadToRemove != null ) {
                        threadToRemove.stop();
                    }

                    break;

                case 3:
                    myThreads.forEach(( Integer t, MyThread u ) -> {
                        u.stop();
                    });
                    es.shutdown();
                    break;

                default:
                    System.err.println( "Wrong option!" );
                    break;
            }


        }

    }

}

【讨论】:

  • 嗨,大卫,感谢您的回答,您的代码运行良好。我可以将它与 Thread 的扩展一起使用吗?就我而言,Receiver 和 Transmitter 是扩展。我应该添加一个构造函数来传递 Runnable 吗?
  • @narraccino 是的,你可以,因为类 Thread 实现了接口 Runnable 并且当你扩展 Thread 类时,你的类也将是一个 Runnable ;) Thread 的状态将由一个控制我编码的线程的实例变量。如果我的回答解决了您的问题,请考虑将其标记为已解决。
  • 它工作!谢谢!
  • 我不推荐使用这种方法。您覆盖已弃用的 java api 并使用 running 标志,我敢打赌您不知道 volatile 做了什么。如果您想以“正确的方式”™,请阅读notify()wait() 并打断:docs.oracle.com/javase/tutorial/essential/concurrency/…
猜你喜欢
  • 2021-11-15
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
相关资源
最近更新 更多