`
wj416073
  • 浏览: 3721 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

[JDK]从Thread.stop到线程取消

阅读更多
         Thread.stop不推荐用了,原因javadoc上给出的链接里面有。大概来讲,是stop会抛出ThreadDeath异常(准确讲是Error),而抛出异常的方法会释放锁(release monitor),其它方法就会访问到本来被锁保护的对象,而这些对象可能处于不一致的状态(没锁保护,但被多线程访问),导致产生不可预知的结果。关键是这种现象很难被观察到,也很难找到原因(根据一个现象,很难发现是stop导致的问题)。很难观察到,是因为它可能有很长的潜伏期,几天之后才会出问题,所谓的“偶发现象”,不能在短时间重现。
        所以一般建议改写run方法,将它用while包起来,while里面判断一个(或若干)状态,再写一个cancle方法取消(或停止)线程,这个cancle会简单,改一下状态就行了。
    private volatile Thread blinker;

    public void stop() {
        blinker = null;
    }

    public void run() {
        Thread thisThread = Thread.currentThread();
        while (blinker == thisThread) {
            try {
                thisThread.sleep(interval);
            } catch (InterruptedException e){
            }
            repaint();
        }
    }

只是要注意一下状态的同步(使用volatile或其它同步方式)
        但java并发编程中,大师发现了这种模式的一个问题,如果while中的动作会阻塞,那么while可能很长时间或永远不会退出。
public void run() {
    try {
        while(!canceled) {
            blockingQueue.put(produceLongTimeJob());
        }
    } catch (InterruptedException ex) {
        /* 允许线程退出 */
    }
}

使用生产者消费者模式,生产者快于消费者,任务队列已经饱和,再调用阻塞队列的put方法就会阻塞,此时只要消费者没有消费任务,整个工作就不会停止,即使调用了停止方法去更改了canceled的状态。
        解决方法java并发编程中也给出了,使用中断。“中断通常是实现取消最明智的选择”。
public void run() {
    try {
        while(!Thread.currentThread().isInterrupted()) {
            blockingQueue.put(produceLongTimeJob());
        }
    } catch (InterruptedException ex) {
        /* 允许线程退出 */
    }
}

这种写法只是加快了中断检测,在生产任务之前如果检测到中断就可以直接退出。其实有try,catch检测中断,逻辑上就可以使用中断来退出了。
        在concurrent包里面,ThreadExecute的工作线程的run方法就是使用while检查状态
public void run() {
    try {
        Runnable task = firstTask;
        firstTask = null;
        while (task != null || (task = getTask()) != null) {
            runTask(task);
            task = null;
        }
    } finally {
        workerDone(this);
    }
}

而在getTask方法中就包括使用中断去通知线程退出
    Runnable getTask() {
        for (;;) {
            try {
                int state = runState;
                if (state > SHUTDOWN)
                    return null;
                Runnable r;
                if (state == SHUTDOWN)  // Help drain queue
                    r = workQueue.poll();
                else if (poolSize > corePoolSize || allowCoreThreadTimeOut)
                    r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
                else
                    r = workQueue.take();
                if (r != null)
                    return r;
                if (workerCanExit()) {
                    if (runState >= SHUTDOWN) // Wake up others
                        interruptIdleWorkers();
                    return null;
                }
                // Else retry
            } catch (InterruptedException ie) {
                // On interruption, re-check runState
            }
        }
    }

interruptIdleWorkers()会中断没做事的工作线程,工程线程检测到中断就会退出。
        所以在多线程编程中,一定要处理中断,因为它很常见,而且为了线程能很好的处理退出,也要处理中断,原因上面讲了。
0
0
分享到:
评论

相关推荐

    java中 如何终止一个线程

    因此,从JDK 1.1开始,`Thread.stop()`方法已经被废弃,并建议不再使用。 #### 二、使用`interrupt()`方法的安全方式 **1. 使用共享变量控制线程的运行** 在许多情况下,我们可以通过一个共享变量(通常是...

    2020版Java多线程 21 道.pdf

    volatile 的区别是什么? ...................................以上就是对Java多线程21道问题的详细解答,涵盖了从基础概念到高级特性的多方面内容。理解和掌握这些知识点对于编写高效、安全的多线程Java程序至关重要。

    最新收集JDK1.5.0命令大全.txt

    这些工具是开发和维护 Java 应用程序的重要组成部分,它们提供了强大的功能,从编译源代码到调试运行时的问题,再到监视和管理运行中的应用。掌握这些工具的使用对于 Java 开发者来说至关重要。

    javascjp线程.pdf

    - 在JDK 1.2之后,`suspend()`、`resume()`和`stop()`方法不再推荐使用,因为它们可能导致线程死锁或资源泄露。开发者应使用更安全的机制,如`synchronized`和`wait/notify`,来控制线程的执行状态。 理解并掌握...

    线程组ThreadGroup

    ThreadGroup 还提供了一些其他的方法,例如 stop() 方法可以停止当前 ThreadGroup 中的所有线程,resume() 方法可以恢复当前 ThreadGroup 中的所有线程,suspend() 方法可以暂停当前 ThreadGroup 中的所有线程等。...

    Java多线程-线程的生命周期

    在JDK1.5及之后,线程的状态增加到六种,新增了等待(Waiting)和暂停(Timed Waiting)状态。接下来,我们将深入探讨这些状态。 1. 新建(New): 当通过`new Thread()`创建一个线程对象时,线程处于新建状态。...

    javaSenior.pdf

    Java是一种广泛使用的编程...综上所述,Java的多线程机制提供了一套完整的框架,从创建线程到管理线程,再到处理并发问题,都有一系列的API和策略。熟练掌握这些知识,能够帮助开发者编写出高效、稳定的多线程程序。

    JAVA核心知识点整理(有效)

    1:eden、servicorFrom 复制到 ServicorTo,年龄+1................................................................................... 25 2:清空 eden、servicorFrom.............................................

    JDK命令学习 javac java javah jdb

    * thread:设置默认线程 * suspend:暂停线程 * resume:恢复线程 * up:向上移动线程的堆栈 * down:向下移动线程的堆栈 * kill:中止线程 * interrupt:中断线程 * print:输出表达式的值 * dump:输出所有对象...

    线程的创建与撤销实验设计报告完整版

    该实验旨在深入理解线程的概念,包括如何创建线程、挂起与恢复线程、终止线程以及使用相关的方法,如`sleep()`、`wait()`、`notify()`和`stop()`。实验者需能够熟练运用`Thread`类创建子线程,重写`run()`方法,同时...

    java7源码-thread:多线程相关的学习

    Stop:终止线程,并且清除监视器锁的信息,但是可能导致线程安全问题,JDK不建议使用。 代码:Demo02 正确的线程中止-interrupt 如果目标线程在调用Object class的wait()、wait(long)或wait(long millis, int nanos)...

    JDK命令大全新手的宝典

    - `threadgroups`: 显示线程组列表。 - `up`: 上移帧。 - `use`: 设置源文件路径。 - `where`: 显示当前位置。 - `-host`: 指定远程主机。 - `-password`: 指定密码。 #### 七、javaws.exe **功能:** Java ...

    浅析java线程中断的办法

    Java中的线程中断机制是在JDK 1.5版本引入的,它取代了早期版本中的Thread.stop()方法,后者已在后续版本中被废弃。Thread.stop()方法能立即停止线程的执行,但由于其安全问题,比如可能会导致数据不一致,因此不再...

    语言程序设计资料:JAVA游戏制作.doc

    尽管`Thread.stop()`方法可以停止一个线程,但由于可能引发安全问题,已不推荐使用。现代的线程控制通常采用其他机制,如共享变量、中断标志或`InterruptedException`。 学习Java游戏编程不仅涉及技术知识,还需要...

    Java游戏编程初步

    - `Thread.stop()`: 停止线程(不推荐使用,因为不安全,可能导致数据不一致)。 - `Thread.join()`: 等待当前线程结束。 - `Thread.sleep()`: 使当前线程暂停指定的毫秒数。 在游戏编程中,线程常用于实现动画、...

    java游戏编程初步.doc

    本文介绍了Java游戏编程的基础知识,从环境搭建、Applet开发到线程处理以及简单的动画技术实现。虽然Java在游戏开发领域的应用不如C或C++广泛,但其强大的功能和易于上手的特点使其成为一个不错的选择,特别是对于...

    一款适合小白的jmeter入门使用,性能测试工具-jmeter使用教程

    ④.Delay Thread creation until need:勾选代表线程将在需要的时候才构建 Ⅴ 调度器 只有在调度器勾选后,才可以进行配置;也只有勾选调度器后,配置的值才能生效 ①.持续时间:即线程的执行时间是多少秒,在达到...

    jcmd:JDK14中的调试神器

    - `Thread.*`:与线程相关的命令,如`Thread.print`。 - `PerfCounter.print`:打印性能计数器信息。 - `-f filename`:从文件中读取要执行的命令。 - `-l`:列出非Docker环境下的所有JVM进程。 - `-h`:显示...

    java线程池概念.txt

    如果继续添加任务到线程池,且线程池中的线程数已经达到了maximumPoolSize,那么线程就会就会执行reject操作(这里后面会提及到) keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止;默认情况下,只有...

Global site tag (gtag.js) - Google Analytics