《Java并发编程》之线程中断与终止线程运行

Java中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止。但有时需要在任务正在运行时取消他们,使得线程快速结束。对此Java并没有提供任何机制。但是我们可以通过Java提供的线程中断机制来实现。

首先来看Thread类三个和中断有关的方法:

public class Thread {
    // 发出一个中断请求,把标志位设定为中断状态,不会终止线程运行。    // 其他线程试图调用该方法,会检测是否有权限中断该线程(正常情况    // 下不会存在权限问题,这里可以忽略)
    public void interrupt() { ... }

    // 检测标志位是否为中断的状态
    public boolean isInterrupted() { ... }

    // 清除当前线程的标志位的中断状态,返回是否为中断状态
    public static boolean interrupted() { ... }

    ...
}

既然线程中断不会终止线程的运行,那么如何通过线程中断来实现终止线程运行呢?

我们知道一些阻塞线程的方法会抛出InterruptedException表示线程中断发生,在这种情况下就可以使用线程中断来终止线程的运行:

public class TestInterrupt {

    public static void main(String[] args)
    {
        BlockingQueue<Object> ObjectQueue = new LinkedBlockingQueue<Object>();
        Consumer consumer = new Consumer(ObjectQueue);

        Thread t = new Thread(consumer);
        t.start();

        // 等待线程的启动
        try
        {
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        // 中断线程
        t.interrupt();
    }

}

class Consumer implements Runnable
{
    private final BlockingQueue<Object> ObjectQueue;
    public Consumer(BlockingQueue<Object> ObjectQueue)
    {
        if (ObjectQueue == null)
        {
            throw new IllegalArgumentException("messageQueue cannot be null");
        }

        this.ObjectQueue = ObjectQueue;
    }

    @Override
    public void run()
    {
        boolean isRunning = true;
        while (isRunning)
        {
            try
            {
                // take方法阻塞时会因为线程中断抛出中断异常
                System.out.println(ObjectQueue.take());
            }
            catch (InterruptedException e)
            {          // 一旦抛出中断异常,线程的中断状态就会被清除,这个时候调用                // Thread的isInterrupted()方法返回的是false
                isRunning = false;
                System.out.println("Cancelled");
            }
        }
    }
}

很多任务执行的服务程序的逻辑和上面的例子很类似,都可以使用这种方法来终止线程的运行。

时间: 2024-08-25 23:57:05

《Java并发编程》之线程中断与终止线程运行的相关文章

java线程中断和终止线程运行

ava中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线程中断机制来实现. 首先来看Thread类三个和中断有关的方法: public class Thread { // 发出一个中断请求,把标志位设定为中断状态,不会终止线程运行. // 其他线程试图调用该方法,会检测是否有权限中断该线程(正常情况 // 下不会存在权限问题,这里可以忽略) public

Java并发编程学习笔记(一)线程安全性 1

什么是线程安全性: 要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的和可变的状态的访问."共享"意味着变量可以由多个线程同时访问,而"可变"则意味着变量的值在其生命周期内可以发生变化. 一个对象是否需要线程安全的,取决于他是否被多个线程访问.这指的是在程序中访问对象的方式,而不是对象要实现的功能.要使得对象时线程安全的,需要采用同步机制来协同对对象可变状态的访问.如果无法实现协同,那么可能导致数据破坏以及其他不该出现的结果. 如果当多个线程访

Java并发编程(十二):线程池的使用(转载)

本文转载自:http://www.cnblogs.com/dolphin0520/p/3932921.html 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间. 那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务? 在Java中可以通过线程池来达到这样的效果.

Java并发编程(4):守护线程与线程阻塞的四种情况

守护线程Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通.非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程.当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出,因为没有如果没有了被守护这,也就没有继续运行程序的必要了.如果有非守护线程仍然存活,VM就不会退出. 守护线程并非只有虚拟机内部提供,用户在

Java 并发编程(一)浅谈线程安全

首先我们要弄清楚什么叫线程安全. "线程安全"是指:当多个线程访问某个类时,不管运行环境采用何种调度方式或者这些线程如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的. 这里有三个关键点, 第一."线程安全"问题是来源于多个线程访问的情况下,当个线程没有竞争便涉及到出现线程安全的问题. 第二.类的"线程安全"性不依赖于多线程的执行顺序. 第三.主调代码不需要同步或协同.某个类"

那些年读过的书《Java并发编程实战》一、构建线程安全类和并发应用程序的基础

1.线程安全的本质和线程安全的定义 (1)线程安全的本质 并发环境中,当多个线程同时操作对象状态时,如果没有统一的状态访问同步或者协同机制,不同的线程调度方式和不同的线程执行次序就会产生不同的不正确的结果.要确保获得最后正确的结果就需要对线程访问对象状态 的操作上进行同步或者协同,使多个线程无论在什么样的调度方式和线程执行顺序的情况中,都能产生正确的结果. 线程安全的本质就对(对象)状态的访问操作进行统一管理,使之在不同的执行环境下均能产生正确的结果.也就是在不同的并发环境下,保持对象状态的不变

《Java并发编程实战》----(八)线程池的使用

1,线程饥饿死锁 在线程池中,如果任务依赖于其他任务,那么可能产生死锁.在单线程的Executor中,如果一个任务将另一个任务提交到同一个Executor,并且等待这个被提交任务的结果,那么通常会引发死锁.第二个任务停留在工作队列中,等待第一个任务完成,而第一个任务又无法完成,因为它在等待第二个任务的完成.在更大的线程池中,如果所有正在执行任务的线程都由于等待其他仍处于工作队列中的任务而阻塞,也会发生统一的问题.这种现象叫做线程饥饿死锁(Thread Starvation Deadlock),只

[Java并发编程之美]第1章 线程基础(待更新)

第1章 线程 线程与进程 进程是操作系统资源分配和调度的基本单位,但cpu资源是分配到线程的,也就是线程是CPU分配的基本单位. 线程自己的栈资源中,存放的局部变量是线程私有的,其他线程无法访问,除此之外栈还存线程的调用栈帧. 线程创建 三种方式:实现Runnable接口的run方法:继承Thread类并重写run方法:使用FutureTask方式. 线程等待与通知 1 wait() 线程先要事先获得共享变量上的监视器锁,然后当一个线程调用一个共享变量的wait()方法,该线程会被阻塞挂起,并且

《Java并发编程实战》第六章 任务运行 读书笔记

一. 在线程中运行任务 无限制创建线程的不足 .线程生命周期的开销很高 .资源消耗 .稳定性 二.Executor框架 Executor基于生产者-消费者模式,提交任务的操作相当于生产者.运行任务的线程则相当于消费者. 1. Executors 返回 ExecutorService 2. ExecutorService方法submit.execute 3. ExecutorService.submit 返回 Future 线程池,Executors方法介绍 方法名 解释 newFixedThre