Java关闭线程的安全方法

Java之前有一个api方法可以直接关闭线程,stop(),由于这个方法是强制性地关闭线程,有的时候会发生错误,之后就取消了,现在可用的方法主要有两种:

1、  在线程中加入一个成员变量,当一个flag使用。在线程run()方法中轮流去检查这个变量,变量变化时就退出这个线程。代码示例如下:

public class StopThread extends Thread {
    private boolean _run = true;
    public void stopThread(boolean run) {
        this._run = !run;
    }
    @Override
    public void run() {
        while(_run) {
            // 数据处理
        }
    }
}

2、  第一个方法虽然可以处理好,不过,在有阻塞线程的语句的时候往往不能处理好,因为线程被阻塞了,它便不能核查成员变量,就不能停止。比如, 涉及到Socket的阻塞语句server.accept().要使用某种机制使得阻塞线程更早地退出被阻塞的状态,这个时候可以使用Thread.interrupt()方法。Interrupt()方法只能解决跑出InterruptedException异常的阻塞。而interrupt()并不是关闭阻塞线程,而且解除阻塞。上一个例子:

public class BlockTask extends Thread {
    @Override
    public void run() {
        try {
            sleep(10000);
        } catch (InterruptedException e) {
        }
    }
    public static void main(String[] args)throws Exception {
        BlockTask task = new BlockTask();
        task.start();
        Thread.sleep(1000);
        task.interrupt();
    }

3、上面说了,interrupt()只能解决InterruptedException的阻塞的线程,那么遇到一些其他的io阻塞怎么处理呢?这个时候java都会提供相应的关闭阻塞的办法。例如,服务器可能需要等待一个请求(request),又或者,一个网络应用程序可能要等待远端主机的响应,这个时候可以使用套接字close()方法。

public class SocketTask extends Thread {
    private volatile ServerSocket server;
    public void stopTask(){
        try {
            if(server!=null){
                server.close();
                System.out.println("close task successed");
            }
        } catch (IOException e) {
            System.out.println("close task failded");
        }
    }
    @Override
    public void run() {
        try {
            server = new ServerSocket(3333);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        SocketTask task = new SocketTask();
        task.start();
        Thread.sleep(1000);
        task.stopTask();
    }
}
时间: 2024-11-05 12:30:50

Java关闭线程的安全方法的相关文章

JAVA中线程同步的方法

用什么关键字修饰同步方法 ? 用synchronized关键字修饰同步方法  同步有几种实现方法,都是什么?分别是synchronized,wait与notify wait():使一个线程处于等待状态,并且释放所持有的对象的lock.sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常.notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线

JAVA中线程同步的方法(7种)汇总

一.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类. 二.同步代码块 即有synchronized关键字修饰的语句块. 被该关键字修饰的语句块会自动被加上内置锁,从而实现同步 代码如: synchronized(object){ } 注:同步是一种高开销

java创建线程两种方法

/* 进程:是一个正在执行中的程序 每一个进程执行都有执行顺序,该顺序是一个执行路径,或叫控制单元 线程:就是进程中一个独立的控制单元 线程在控制着进程的执行 一个进程至少包含一个线程 Java VM 启动时会有个进程java.exe 该进程中至少有一个线程复制java程序的执行,这个线程运行的代码存在于main方法中, 该线程称之为主线程 JVM启动不止一个线程,还有复制垃圾回收机制的线程 创建线程:(1)继承Thread类;复写run方法;创建对象,调用start方法 (2)实现Runnab

java 关闭线程

public class ThreadService { private Thread executeThread; private boolean finished = false; public void execute(Runnable task) { executeThread = new Thread() { @Override public void run() { Thread runner = new Thread(task); runner.setDaemon(true); r

linux环境中关闭tomcat,通过shutdown.sh无法彻底关闭--线程池

最近测试环境上测试的项目通过shutdown.sh始终无法彻底关闭. 之前临时解决方法两种: 第一:通过ps -ef|grep tomcat查看到tomcat的进程直接使用kill来杀死进程. 第二: 基本原理为启动tomcat时记录启动tomcat的进程id(pid),关闭时强制杀死该进程 1.找到tomcat下bin/catalina.sh文件,vi进去添加点东西,主要是记录tomcat的pid,如下: 大概在第125行左右,添加如下代码 #设置CATALINA_PID(后加)if [ -z

同步方法 sleep和wait 线程同步的方法

当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 分两种情况 1):进入此对象的非同步方法 答案:可以 2):进入此对象的同步方法 答案:不可以 sleep指线程被调用时,占着CPU不工作,形象地说明为"占着CPU睡觉",此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制.wait指线程处于进入等待状态,形象地说明为"等待使用CPU",此时线程不占用任何资源,不增加时间限制.所以sleep(100L)意

JAVA并发编程9_正确关闭线程

Java没有提供任何的安全机制来终止线程,程,虽然Thread.stop和suspend等方法提供了这样的机制,但是存在严重的缺陷,应该避免使用这些方法. 它提供了中断(interrupt),这是一种协作机制,能够使一个线程终止另一个线程当前的工作. 一种协作机制是设置一个"已请求取消(Cancellation Requested)"标志,而任务定期查看该标志. "已请求取消"标志 private volatile boolean cancelled; public

Java多线程系列一——Java实现线程方法

Java实现线程的两种方法 继承Thread类 实现Runnable接口 它们之间的区别如下: 1)Java的类为单继承,但可以实现多个接口,因此Runnable可能在某些场景比Thread更适用2)Thread实现了Runnable接口,并且有更多实用方法3)实现Runnable接口的线程启动时仍然需要依赖Thread import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.junit.As

(转)java创建线程的两种方法比较

Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线程,有两种方法: ◆需要从Java.lang.Thread类派生一个新的线程类,重载它的run()方法:  ◆实现Runnalbe接口,重载Runnalbe接口中的run()方法. 为什么Java要提供两种方法来创建线程呢?它们都有哪些区别?相比而言,哪一种方法更好呢? 在Java中,类仅支持单继承