并发----终结任务

  • cancel() and isCancel()

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by Panda on 2018/6/5.
 */
//终止和资源共享实例
class Count{
    private int count=0;
    private Random random = new Random(47);
    public synchronized int increment(){
        int temp=count;
        if(random.nextBoolean())
            Thread.yield();
        return (count=++temp);
    }
    public synchronized int value(){return count;}
}

class Entrance implements Runnable{
    private static Count count = new Count();
    private static List<Entrance> entrances=new ArrayList<>();
    private int number=0;
    private final int id;
    private static volatile boolean canceled=false;
    public static void cancel(){canceled=true;}

    public Entrance(int id) {
        this.id = id;
        entrances.add(this);
    }

    @Override
    public void run() {
        while (!canceled){
            synchronized (this){
                ++number;
            }
            System.out.println(this+" Total; "+count.increment());
            try{
                TimeUnit.MILLISECONDS.sleep(100);
            }catch (InterruptedException e){
                System.out.println("sleep interrupted");
            }
        }
        System.out.println("Stopping "+this);
    }

    public synchronized int getValue(){return number;}
    public String toString(){
        return "Entrance "+id+": "+getValue();
    }

    public static int getTotalCount(){
        return count.value();
    }

    public static int sumEntrances(){
        int sum=0;
        for(Entrance entrance:entrances){
            sum+=entrance.getValue();
        }
        return sum;
    }
}
public class OrnamentalGarden {
    public static void main(String[] args) throws Exception{
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i <5 ; i++) {
            executorService.execute(new Entrance(i));
        }

        TimeUnit.SECONDS.sleep(3);
        Entrance.cancel();
        executorService.shutdown();
        if(!executorService.awaitTermination(250,TimeUnit.MILLISECONDS))
            System.out.println("some tasks were not terminated");
        System.out.println("Total: "+Entrance.getTotalCount());
        System.out.println("Sum of Entrances: "+Entrance.sumEntrances());
    }
}

在阻塞时终结

线程状态:

  • 新建:当线程被创建时,只会短暂地处于这种状态,此时已经分配了必需的系统资源,并执行了初始化。此刻线程已经有资格获得CPU时间了,之后调度器将把这个线程转变为可运行状态或阻塞状态。
  • 就绪:在这种状态下,只要调度器把时间片分配给线程,线程就可以运行。也就是说,在任意时刻,线程可以运行也可以不运行。只要调度器能分配时间片给线程,它就可以运行,这不同于死亡和阻塞状态。
  • 阻塞:线程能够运行,但有某个条件阻止它的运行。当线程处于阻塞状态时,调度器将忽略线程,不会分配给线程任何CPU时间。直到线程重新进入了就绪状态,它才有可能执行操作。
  • 死亡:处于死亡或终止状态的线程将不再是可调度的,并且再也不会得到CPU时间,它的任务已结束,或不再是可运行的。任务死亡的通常方式是从run()方法返回,但是任务的线程还可以被中断。

进入阻塞状态:

  • 通过调用sleep(milliseconds)使任务进入休眠状态,在这种情况下,任务在指定的时间内不会运行。
  • 通过调用wait()使线程挂起。直到线程得到了notify()或者notifyAll()消息,线程才会进入就绪状态。
  • 任务在等待某个输入/输出完成。
  • 任务试图在某个对象上调用其同步控制方法,但是对象锁不可用,因为另一个任务已经获取了这个锁。
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * Created by Panda on 2018/6/5.
 */
class SleepBlocked implements Runnable{
    @Override
    public void run() {
        try{
            TimeUnit.SECONDS.sleep(100);
        }catch (InterruptedException e){
            System.out.println("interruptedException");
        }
        System.out.println("Exiting sleepBlocked.run()");
    }
}

class IOBlocked implements Runnable{
    private InputStream inputStream;

    public IOBlocked(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    @Override
    public void run() {
        try {
            System.out.println("Waiting for read()");
            inputStream.read();
        }catch (IOException e){
            if(Thread.currentThread().isInterrupted()){
                System.out.println("Interrupted from blocked I/O");
            }else{
                throw new RuntimeException(e);
            }
        }
        System.out.println("Exiting IOBlocked.run()");
    }
}

class SynchronizedBlocked implements Runnable{
    public synchronized void f(){
        while (true) Thread.yield();
    }

    public SynchronizedBlocked() {
        new Thread(){
            public void run(){
                f();
            }
        }.start();
    }

    @Override
    public void run() {
        System.out.println("Trying to call f()");
        f();
        System.out.println("Exiting SynchronizedBlocked.run()");
    }
}
public class Interrupting {
    private static ExecutorService executorService = Executors.newCachedThreadPool();
    static void test(Runnable runnable) throws Exception{
        Future<?> future = executorService.submit(runnable);
        TimeUnit.MILLISECONDS.sleep(100);
        System.out.println("Interrupting "+runnable.getClass().getName());
        future.cancel(true);
        System.out.println("Interrupt send to "+runnable.getClass().getName());
    }

    public static void main(String[] args) throws Exception {
        test(new SleepBlocked());
        test(new IOBlocked(System.in));
        test(new SynchronizedBlocked());

        TimeUnit.SECONDS.sleep(3);
        System.out.println("Aborting with System.exit(0)");
        System.exit(0);
    }
}
/**
*
 Interrupting com21前半部分.SleepBlocked
Interrupt send to com21前半部分.SleepBlocked
interruptedException
Exiting sleepBlocked.run()
Waiting for read()
Interrupting com21前半部分.IOBlocked
Interrupt send to com21前半部分.IOBlocked
Trying to call f()
Interrupting com21前半部分.SynchronizedBlocked
Interrupt send to com21前半部分.SynchronizedBlocked
Aborting with System.exit(0)
**/

SleepBlock是可中断的阻塞示例,而IOBlocked和SynchronizedBlocked是不可中断的阻塞。

/**
 * Created by Panda on 2018/6/5.
 */
//可以通过关闭底层资源来释放锁
class NIOBlocked implements Runnable{
    private final SocketChannel socketChannel;

    public NIOBlocked(SocketChannel socketChannel) {
        this.socketChannel = socketChannel;
    }

    @Override
    public void run() {
        try{
            System.out.println("Waiting for read() in "+this);
            socketChannel.read(ByteBuffer.allocate(1));
        }catch (ClosedByInterruptException e){
            System.out.println("ClosedByInterruptException");
        }catch (AsynchronousCloseException e){
            System.out.println("AsynchronousCloseException");
        }catch (IOException e){
           throw new RuntimeException(e);
        }
        System.out.println("Exiting NIOBlocked.run() "+this);
    }
}
public class NIOInterruption {
    public static void main(String[] args) throws Exception{
        ExecutorService executorService = Executors.newCachedThreadPool();
        ServerSocket serverSocket = new ServerSocket(8080);
        InetSocketAddress isa=new InetSocketAddress("localhost",8080);
        SocketChannel socketChannel1=SocketChannel.open(isa);
        SocketChannel socketChannel2=SocketChannel.open(isa);
        Future<?> future=executorService.submit(new NIOBlocked(socketChannel1));
        executorService.execute(new NIOBlocked(socketChannel2));
        executorService.shutdown();

        TimeUnit.SECONDS.sleep(1);
        future.cancel(true);
        TimeUnit.SECONDS.sleep(1);
        socketChannel2.close();

    }
}

只要任务以不可中断的方式被阻塞,都有潜在的会锁住程序的可能。

//ReentrantLock上阻塞的任务具备可以被中断的能力
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Panda on 2018/6/5.
 */
class BlockedMutex{
    private Lock lock=new ReentrantLock();

    public BlockedMutex( ) {
        lock.lock();
    }

    public void f(){
        try{
            lock.lockInterruptibly();
            System.out.println("lock acquired in f()");
        }catch (InterruptedException e){
            System.out.println("Interrupted from lock acquisition in f()");
        }
    }
}

class Blocked2 implements Runnable{
    BlockedMutex blockedMutex = new BlockedMutex();
    @Override
    public void run() {
        System.out.println("waiting for f() in blockedMutex");
        blockedMutex.f();
        System.out.println("Broken out of blocked call");
    }
}
public class Interrupting2 {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new Blocked2());
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("Issuing t.interrupt()");
        thread.interrupt();
    }
    /**
     * waiting for f() in blockedMutex
     Issuing t.interrupt()
     Interrupted from lock acquisition in f()
     Broken out of blocked call
     */
}

猜你喜欢

转载自blog.csdn.net/panda_____/article/details/80585769