java线程取消方式

JAVA任务取消方式一般有2种
第一种设置某个取消标志,任务定期查看该标志,这种方式存在任务取消并不能保证任务立即取消,更糟糕的是有可能任务永远不会结束
第二种是利用的中断机制,JVM并不能保证阻塞方法检测到中断的速度,但是实际中还是非常快的。
实例一(使用取消标志,会发现取消的任务还执行中,只有执行完再次检测标志任务才取消)
任务不断获取下一个素数,在每次获取素数利用sleep 保证获取素数时间大约10s

package org.thread;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public class PrimeGenerator extends Thread {

    private final List<BigInteger> primes=new ArrayList<BigInteger>();
    private volatile boolean cancelled;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        BigInteger p=BigInteger.ONE;
        while(!cancelled){
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            p=p.nextProbablePrime();
            synchronized (this) {
                primes.add(p);
            }
        }
        
    }
    public void cancell(){cancelled=true;};
    public synchronized List<BigInteger> get(){
        return new ArrayList<BigInteger>(primes);
    }

}

测试程序中在启动获取素数的线程后,1s后取消获取素数线程,结果可以看出,线程真正结束是在9s后,结论利用取消标志不能保证线程立即结束或结束。

package org.thread;

public class InterruptTest {

    public static void main(String[] args) {
        PrimeGenerator t=new PrimeGenerator();
//        PrimeGenerator1 t=new PrimeGenerator1();
        t.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t.cancell();
        long start=System.currentTimeMillis();
        long end=0;
        while(t.isAlive()){
             end=System.currentTimeMillis();
        }
        System.out.println(end-start);
    }

}

实例 二(使用中断取消,会发现取消的任务很快就结束)
任务不断获取下一个素数,在每次获取素数利用sleep 保证获取素数时间大约10s

package org.thread;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public class PrimeGenerator1 extends Thread{

    private final List<BigInteger> primes=new ArrayList<BigInteger>();
    @Override
    public void run() {
        // TODO Auto-generated method stub
        BigInteger p=BigInteger.ONE;
        while(!Thread.currentThread().isInterrupted()){
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                Thread.currentThread().interrupt();
                e.printStackTrace();
            }
            p=p.nextProbablePrime();
            synchronized (this) {
                primes.add(p);
            }
        }
        
    }
    public void cancell(){interrupt();};
    public synchronized List<BigInteger> get(){
        return new ArrayList<BigInteger>(primes);
    }

}

测试程序中在启动获取素数的线程后,1s后取消获取素数线程,结果可以看出,线程可以立即结束。

package org.thread;

public class InterruptTest {

    public static void main(String[] args) {
//        PrimeGenerator t=new PrimeGenerator();
        PrimeGenerator1 t=new PrimeGenerator1();
        t.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t.cancell();
        long start=System.currentTimeMillis();
        long end=0;
        while(t.isAlive()){
             end=System.currentTimeMillis();
        }
        System.out.println(end-start);
    }

}
posted @ 2016-03-03 16:18  熊猫太郎  阅读(349)  评论(0编辑  收藏  举报