Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从方法中断线程_Java_Android_Multithreading - Fatal编程技术网

Java 从方法中断线程

Java 从方法中断线程,java,android,multithreading,Java,Android,Multithreading,我想用interrupt()方法中断线程,但是我遇到了一种无法解释的行为 如代码所示,从MainActivity调用worker方法cancel()不能中断线程,而调用workerThread.interrupt()可以中断线程 如果工作进程自己调用cancel(),则会中断 除非当前线程中断自身(这是始终允许的),否则将调用此线程的checkAccess方法,这可能会导致抛出SecurityException 我认为这可能是一个安全异常,因为UIThread试图中断workerThread,但

我想用interrupt()方法中断线程,但是我遇到了一种无法解释的行为

如代码所示,从MainActivity调用worker方法cancel()不能中断线程,而调用workerThread.interrupt()可以中断线程

如果工作进程自己调用cancel(),则会中断

除非当前线程中断自身(这是始终允许的),否则将调用此线程的checkAccess方法,这可能会导致抛出SecurityException

我认为这可能是一个安全异常,因为UIThread试图中断workerThread,但没有抛出它。如果是,那么在调用workerThread.interrupt()时也应该抛出它


Worker.java

package com.example.threadapp;
public class Worker implements Runnable {

    public void cancel() {
        Log.d("Threading", "call Thread.currentThread().interrupt()");
        try {
            Thread.currentThread().interrupt();
        } catch (SecurityException e) {
            e.printStackTrace();
            Log.d("Threading", "SecurityException while interrupting");
        }

    }

    @Override
    public void run() {
        //
        while(!Thread.currentThread().isInterrupted()) {
            Log.d("Threading", "Worker alive");
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
                cancel();
            }
            //cancel(); //interrupts thread
            //Thread.currentThread().interrupt(); //interrupts thread

        }
        //
        Log.d("Threading", "Worker Thread closing");
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private Worker worker;
    private Thread workerThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        worker = new Worker();
        workerThread = new Thread(worker);
        workerThread.start();

        (new Handler(Looper.getMainLooper())).postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.d("Threading", " call worker.cancel()");
                worker.cancel(); //doesn't interrupt thread
                //workerThread.interrupt(); //interrupts thread
            }
        }, 10000);
    }
}

在主线程中调用了
worker.cancel
。因此,cancel方法中的
Thread.currentThread()
返回主线程,因此主线程调用了
interrupt
方法。在这种情况下,您没有中断工作线程。

但workerThread.interrupt()不是也从主线程调用的吗?interrupt方法在工作线程内切换标志变量。因此,当调用isInterrupted时,它将返回该值。因此,无论你在哪里称呼它都无关紧要。另一方面,当调用mainThread.interrupt时,它会切换主线程的标志变量。在这种情况下,isInterrupted将始终返回false,因为它不知道来自主线程的值。如果它只是一个标志,并且从何处设置它并不重要,为什么(从主线程调用)worker.cancel()不会中断线程和workerThread.interrupt();will?记住while循环在工作线程上运行,对吗?这是在调用workerThread.start()时发生的。因此,当您调用Thread.currentThread.isInterrupted时,实际上是在调用workerThread.isInterrupted。该方法要求提供workerThread内部变量的值。调用workerThread.interrupt时,该变量已更改。因此,在主线程中调用它并不重要,您将能够更改该变量。调用worker.cancel时调用mainThread.interrupt时,isInterrupted所需的变量没有更改,而是更改了主线程内的变量。记住,询问的是workerThread中的变量。如果要检查所处的线程,可以使用Thread.currentThread.getName。您将看到cancel方法中的代码确实在主线程中运行。