【问题标题】:How to properly terminate/clear/stop/cancel a thread that was started from another thread?如何正确终止/清除/停止/取消从另一个线程启动的线程?
【发布时间】:2013-03-06 04:49:25
【问题描述】:

我的一个线程正在创建另一个线程以在特定时间间隔内执行某些操作。它是通过计时器来完成的。

现在当原线程停止时,另一个线程仍在运行,我无法让它停止。

如何正确终止“线程”?:

Thread thread = new Thread() {

    @Override
    public void run() {
        try {
            while (true) {
                sleep(1000);
                // do something
            }
        } catch (InterruptedException e) {
            Log.e(TAG,"new invoked caught the exception!");
            return;
        }
    }
};

public void run() {
    while (true) {
        try {
            Log.d(TAG,"ConnectedThread.run: Reading from InStream socket");
            while (true) {
                thread.start();
                Log.e(TAG,"starting additional thread");
                // Read from the InputStream
                int inB;
                inB = mmInStream.read();
                if (inB != -1) mAccessoryInfo.addCharacter((byte) inB);
            }
        } catch (IOException e) {
            Log.e(TAG, "TADA InStream read exception, disconnected "
                    + e.getMessage());
            // stopService(new Intent(getBaseContext(), Pinger.class));
            thread = null;
            connectionLost();
            break;
        }
    }
}

【问题讨论】:

  • 一般来说,你不想在你的线程中有一个 while(true) 循环。创建一个标志变量(例如“running”)并改用 while(running)。这允许线程在 running=false 时自行结束,您可以使用 Thread.join() 阻塞直到它结束。
  • 如果你启动的第二个线程本质上可以循环运行,你可以考虑使用布尔值来跳出循环,让它优雅地终止,而不是中断它或尝试阻止它。就像上面的 thomas88wp 建议的那样

标签: java android multithreading


【解决方案1】:
Hi thread is stop by kill() or stop() or destroy method of thread but this all are              
deprecated so dont kill the thread thread is automatically destroy after done its work.   
 so   
if you want to do any work use handler like this not thread in therad.
new Thread() {

        public void run() {

            try {
                Message msg = new Message();
                msg.arg2 = 0;
                handle.sendMessage(msg);
                Thread.sleep(5000);
            } catch (Exception e) {
                Log.e("tag", e.getMessage());
            }

            //

        }

    }.start();
 and make handler in ur activity like this
 public static Handler handle = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (msg.arg2 == 0) {
            Toast.makeText(context, "No data to sync.",    
  Toast.LENGTH_SHORT)
                    .show();
        } else if (msg.arg2 == 1) {
            Toast.makeText(context, "Data Sync Completed.",
                    Toast.LENGTH_SHORT).show();

        } else {
            Toast.makeText(context, "Data Sync not Completed.",
                    Toast.LENGTH_SHORT).show();
        }

    }
};

【讨论】:

    【解决方案2】:

    你会想要中断线程。 “正常”的事情是将while(true) 更改为while(!isInterrupted),但是当您在while 循环上方捕获该异常时,它会在您中断它时进入catch 块。您可以通过调用thread.interrupt() 来中断线程。

    【讨论】:

      【解决方案3】:

      根据您的意愿,可能需要一个或多个处理程序/循环器线程。

      Looper 文档http://developer.android.com/reference/android/os/Looper.html 中给出了代码示例, 和处理程序类 http://developer.android.com/reference/android/os/Handler.html 提供您可能使用的方法(如 postAtTime())。

      【讨论】:

        【解决方案4】:

        当您说您有一个“线程”启动另一个“线程”时,我有点困惑,您的意思是Activity 正在启动一个线程,而Activity 被销毁并留下一个孤立线程运行?如果是这种情况,那么我会请求关闭 Activity's onDestroy() 方法中的线程。

        onDestroy()内:

          ...
          if(yourThread != null){
            yourThread.interrupt();
          }
          ...
        

        但我有点担心使用这样的计时器,没有其他方法可以实现您的目标吗?即,异步任务和使用任务何时开始/完成的标志

        【讨论】:

        • 您必须先中断yourThread,然后再将其设置为null,否则它会抛出NullPointerException。此外,没有必要将其设置为 null。
        【解决方案5】:

        只需在 java util 并发框架中使用 callable 语句。

        父线程代码会是这样的

        public class Worker implements Callable<Boolean>
        {
            @Override
            public Boolean call() throws Exception 
            { 
                //Your worker code here
            }
        }
        
        void callingmethod()
        {
            //Three threads executing upon five worker modules.
        
            ExecutorService executor = Executors.newFixedThreadPool(3); 
        
            List<Worker> list = new ArrayList<Worker>(5);  //For example 5 workers.
        
            for(int i=0; i<5; i++)
            {
                list.add(new Worker());
            }
        
            List<Future<Boolean>> futures = executor.invokeAll(list);
        
            for(Future<Boolean> future : futures)
            {
            future.get();
            }
        
            executor.shutdown();
        
            executor.awaitTermination(5, TimeUnit.SECONDS);
        }
        

        future.get 语句的意思是,运行调用方法的线程将阻塞,直到所有worker在执行完工作后返回。

        【讨论】:

          猜你喜欢
          • 2020-06-24
          • 1970-01-01
          • 1970-01-01
          • 2021-11-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多