Java runnable存储对其自身运行线程的引用时有任何注意事项吗?

Java runnable存储对其自身运行线程的引用时有任何注意事项吗?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我有一个长时间运行的可运行对象,我想提供一种比在对象运行的线程上调用中断更优雅的中断机制 前代码: public class MyRunnable implements Runnable { public void run() { while(!Thread.currentThread().isInterrupted()) { //do stuff } } } public class MyClass { publ

我有一个长时间运行的可运行对象,我想提供一种比在对象运行的线程上调用中断更优雅的中断机制

前代码:

public class MyRunnable implements Runnable {
    public void run() {
        while(!Thread.currentThread().isInterrupted()) {
            //do stuff
        }
    }
}

public class MyClass {
    public static void main(String[] args) {
        Runnable myRunnable = new MyRunnable();
        Thread t = new Thread(myRunnable, "myRunnableThread");
        t.start();

        //do stuff

        t.interrupt();

        //do stuff
    }
}
以及新守则:

public class MyRunnable implements Runnable {
    private Thread myThread = null;
    public void run() {
        myThread = Thread.currentThread();
        while(!myThread.isInterrupted()) {
            //do stuff
        }
    }

    public void shutdown() {
        if (myThread != null) {
            myThread.interrupt();
            //do other shutdown stuff
        }
    }
}

public class MyClass {
    public static void main(String[] args) {
        Runnable myRunnable = new MyRunnable();
        Thread t = new Thread(myRunnable, "myRunnableThread");
        t.start();

        //do stuff

        myRunnable.shutdown();

        //do stuff
    }
}
我的问题是,持有对自己线程的引用,并通过公共方法(如上所述)提供对该线程的有限访问,是否会导致可能的副作用或未知因素?这是假设没有人直接调用
run()
方法,它总是从一个新线程开始


我知道我可以在
run()
shutdown()
方法中使用volatile或原子布尔值来传达关闭意图,我更感兴趣的是学习而不是解决方案。但解决方案仍然是受欢迎的

它已经有了一个参考:

Thread.currentThread()
从:

返回对当前执行的线程对象的引用


对我来说,您的第一种方法更好,因为它不太容易出错,而且更“标准”。但实际上,您试图实现的已经存在(这证明它是有意义的,而且这不是一个坏的实践,但要正确地实现它并不容易),它被调用,而不是使用
true
作为
maybruitrunning
的值关闭,如果您想中断运行任务的线程,我引用javadoc:

试图取消此任务的执行。如果 该任务已完成、已取消或可能无法执行 不能因为其他原因取消。如果成功,此任务 调用cancel时未启动,此任务不应运行。如果 任务已启动,则
可能会中断fRunning
参数确定执行此任务的线程是否应 在试图停止任务时被中断

例如:

// Task that will only sleep for 1 sec and print a message on interrupted
FutureTask<Void> myRunnable = new FutureTask<>(
    new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            try {
                System.out.println("Sleep");
                Thread.sleep(1_000L);
            } catch (InterruptedException e) {
                System.out.println("Interrupted !!!");
                throw e;
            }
            return null;
        }
    }
);
new Thread(myRunnable, "myRunnableThread").start();

// Wait long enough to make sure that myRunnableThread is sleeping 
Thread.sleep(500L);
// Cancel the task and interrupt myRunnableThread
myRunnable.cancel(true);
Sleep
Interrupted !!!

请注意,
isInterrupted
是一种方法,而不是field@NicolasFilotto只是一个输入错误,但你是绝对正确的。所以你的答案是Runnable存储对其执行线程的本地引用绝对没有任何警告/副作用,提供使用该线程的公共方法?我查看了
FutureTask
源代码,它们确实存储了对当前正在执行的线程的内部引用,因此,至少如果我使用与它们类似的引用,我不应该期望它们没有记录的任何古怪行为。我接受了这个答案,尽管它更像是一个解决方案,而不是对我最初问题的回答。