Java Thread part 2

來源:互聯網
上載者:User

線程的四種狀態

1. 建立(new) : 在一個線程建立時會短暫的處於這種狀態,之後調度器可以將其轉為就緒或阻塞

2. 就緒(runnable) : 這種狀態下,線程在任意時間可以運行,也可以不運行

3. 阻塞(blocked) : 這種狀態下,線程被阻止運行。只有當其重新進入就緒狀態才能繼續運行

4. 死亡(dead) : 線程不再可調度

 

進入阻塞狀態的原因

1. sleep() 方法的調用

2. Object類的wait()方法的調用,直到收到notify()或notifyAll()的訊息

3. 線程任務在等待輸入

4. 在調用同步方法而對象鎖不可用時

 

下面是一個阻塞線程的中斷例子

package threadtest2;import java.util.concurrent.TimeUnit;public class SleepBlocked extends Thread {    /**     * 進入一秒的睡眠阻塞     */    @Override    public void run() {        try {            TimeUnit.MILLISECONDS.sleep(1000);        } catch (InterruptedException e) {            System.out.println("Sleep blocked has been interrupted");        }    }}package threadtest2;import java.io.IOException;import java.io.InputStream;public class IOBlocked extends Thread {    InputStream in;        public IOBlocked(InputStream is) {        this.in = is;    }    /**     * 等待輸入進入IO阻塞     */    @Override    public void run() {        System.out.println("Waiting for read");        try {            in.read();        } catch (IOException e) {            if (Thread.currentThread().isInterrupted()) {                System.out.println("IOBlock is interrupted");            } else {                throw new RuntimeException(e);            }        }        System.out.println("Exiting IOBlocked.run()");    }}package threadtest2;public class SyncBlocked extends Thread {    /**     * 線程構造方法內即調用f()     */    public SyncBlocked() {        (new Thread() {            @Override            public void run() {                f();            }        }).start();    }        /**     * 永不釋放的鎖方法     */    public synchronized void f() {        while (true);    }        /**     * 調用f()時進入阻塞     */    @Override    public void run() {        System.out.println("Trying to call f()");        f();        System.out.println("Exiting SyncBlocked.run()");    }}package threadtest2;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;public class Interrupting {    private static ExecutorService exec =            Executors.newCachedThreadPool();    private static void test(Runnable r) throws InterruptedException {        Future<?> f = exec.submit(r);        TimeUnit.MILLISECONDS.sleep(100);        System.out.println("Interrupting " + r.getClass().getName());        f.cancel(true);    // 通過Future的cancel()方法中斷線程運行,和interrupt()效果一致        System.out.println("Interrupt signal sent to " + r.getClass().getName());    }        /**     * 最後的輸出證明sleep阻塞可以被中斷     * 而IO和Sync的阻塞不可被中斷     * @param args     * @throws Exception     */    public static void main(String[] args) throws Exception {        test(new SleepBlocked());        test(new IOBlocked(System.in));        test(new SyncBlocked());        TimeUnit.SECONDS.sleep(3);        System.out.println("Aborting with System.exit(0)");        System.exit(0);    }}

 

1) 通過關閉使用資源來中止阻塞

package threadtest2;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class CloseResource {    public static void main(String[] args) throws Exception {        ExecutorService exec = Executors.newCachedThreadPool();        ServerSocket ss = new ServerSocket(8080);        InputStream socketInput =                 new Socket("localhost", 8080).getInputStream();        exec.execute(new IOBlocked(socketInput));        exec.execute(new IOBlocked(System.in));        TimeUnit.MILLISECONDS.sleep(100);        System.out.println("Shutting down all threads");        exec.shutdownNow();    // 至此所有線程是不能關閉的        TimeUnit.SECONDS.sleep(1);        System.out.println("Closing " + socketInput.getClass().getName());        socketInput.close();    // 只有當正在使用的資源關閉後才能關閉線程        TimeUnit.SECONDS.sleep(1);        System.out.println("Closing " + System.in.getClass().getName());        System.in.close();    }}

Waiting for read
Waiting for read
Shutting down all threads
Closing java.net.SocketInputStream
IOBlock is interrupted
Exiting IOBlocked.run()
Closing java.io.BufferedInputStream

IOBlock is interrupted
Exiting IOBlocked.run()

 

2) 通過使用NIO來響應阻塞的IO線程的插斷要求

package threadtest2;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.channels.AsynchronousCloseException;import java.nio.channels.ClosedByInterruptException;import java.nio.channels.SocketChannel;public class NIOBlocked extends Thread {    private final SocketChannel sc;    public NIOBlocked(SocketChannel sc) { this.sc = sc; }    @Override    public void run() {        System.out.println("Waiting for read in " + this);        try {            sc.read(ByteBuffer.allocate(1));        } catch (ClosedByInterruptException e) {            // 一個通過interrupt()或者cancel()來中斷阻塞的異常            System.out.println("ClosedByInterruptException accured");        } catch (AsynchronousCloseException e) {            // 一個通過關閉正在使用的資源中斷阻塞的異常            System.out.println("AsynchronousCloseException accured");        } catch (IOException e) {            throw new RuntimeException(e);        }        System.out.println("Exiting NIOBlocked.run() " + this);    }}package threadtest2;import java.io.IOException;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.nio.channels.SocketChannel;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;public class NIOInterrupting {    public static void main(String[] args) throws Exception {        ExecutorService exec = Executors.newCachedThreadPool();        ServerSocket ss = new ServerSocket(8080);        InetSocketAddress isa =                new InetSocketAddress("localhost", 8080);        SocketChannel sc1 = SocketChannel.open(isa);        SocketChannel sc2 = SocketChannel.open(isa);        Future<?> f = exec.submit(new NIOBlocked(sc1));        exec.execute(new NIOBlocked(sc2));        exec.shutdown();        TimeUnit.SECONDS.sleep(1);        f.cancel(true);    // 使用NIO可以直接cancel掉阻塞的thread        TimeUnit.SECONDS.sleep(1);        sc2.close();    // 也可以通過close正在使用的資源來    }}

Waiting for read in Thread[Thread-0,5,main]
Waiting for read in Thread[Thread-1,5,main]
ClosedByInterruptException accured
Exiting NIOBlocked.run() Thread[Thread-0,5,main]
AsynchronousCloseException accured
Exiting NIOBlocked.run() Thread[Thread-1,5,main]

 

一個可以被中斷的鎖

package threadtest2;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.ReentrantLock;public class LockBlocked extends Thread {    ReentrantLock lock = new ReentrantLock();        public LockBlocked() {        lock.lock();    }        @Override    public void run() {        System.out.println("Waiting for lock");        try {            // 這是一個可以被interrupt打斷的鎖            lock.lockInterruptibly();        } catch (InterruptedException e) {            System.out.println("Interrupted from LockBlocked.run()");        }        System.out.println("Broken out of constructor lock");    }        public static void main(String[] args) throws InterruptedException {        Thread t = new LockBlocked();        t.start();        TimeUnit.SECONDS.sleep(2);        t.interrupt();    }}

Waiting for lock
Interrupted from LockBlocked.run()
Broken out of constructor lock

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.