亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

Java多線程之一

標簽:
Java

是没有调用start方法        RUNNABLE,//可运行 表示当前线程可以运行,但实际是否运行有cpu决定        BLOCKED,//阻塞 其他线程获得锁,当前线程被阻塞在获得锁处        WAITING,//等待 等待其他条件成熟进入可运行状态        TIMED_WAITING,//计时等待 在一个指定时间内等待,超时后放弃        TERMINATED;//终止 线程执行完毕    }

线程的创建方式

Thread

继承Thread类:

class TestThread extends Thread{        @Override
        public void run() {            super.run();            //do working
        }
    }
Runnable

实现Runnable接口:

static class TestRunnale implements Runnable{        @Override
        public void run() {            //do working
        }
    }    public static void main(String[] args) {
        TestRunnale runnale = new TestRunnale();
        Thread thread = new Thread(runnale);
        thread.start();
    }

线程的中断

不安全的中断

Thread的api中提供了一些终止线程的方法,比如stop()suspend(),resume(),但是这些方法目前在JDK中已经被标记位过时,因为这些方法具有死锁倾向,已经被明确表示不支持使用。

中断线程API

interrupt() 中断线程,本质是将线程的中断标志位设为true,其他线程向需要中断的线程打个招呼。是否真正进行中断由线程自己决定。

isInterrupted() 线程检查自己的中断标志位

静态方法Thread.interrupted() 将中断标志位复位为false

中断标志位

自定义一个Boolean类型的中断标志位,提供一个中断方法,线程一直循环检测该标志位,标志位被设置为退出状态是终止线程。

public class FlagCancel {    static class Flag extends Thread{        //中断标志
        public static boolean flag = false;        @Override
        public void run() {            int i = 0;            while(!flag){
                System.out.println(i++);                if(i>=3){                    try {
                        Thread.sleep(200);                        //interrupt();
                        if(i == 10)
                            cancel();//修改中断状态,退出线程
                        System.out.println("thread:" + isInterrupted());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("cancel...");
                }
            }
        }        public static void cancel(){
            flag = true;
        }
    }    public static void main(String[] args) {
        Flag test = new Flag();
        test.start();
        test.setPriority(10);//这里的设置优先级其实没什么用。cpu不会理你的。。。
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main:" + test.isInterrupted());//这里属于主线程(main)
    }
}

正常来说上面的形式没有什么问题,我们写代码的时候,提供一个修改中断为状态的方法,并根据我们自己的业务逻辑来定义什么时候中断,但是如果我们手动设置中断就有问题了,将上面代码中注释的interrupt();打开。interrupt()方法是用来中断线程的,但是在上面的逻辑中即使调用了该方法也不会立即中断,而必须要等待中断为被修改后才能退出。

安全的中断

上面介绍了中断相关的api和使用中断标志位来中断线程,但是中断标记位无法捕获异常情况。但是isInterrupted()方法会一直检查线程的中断状态,所以我们可以用这个方法来实现安全的中断。

public class SafeInterrupt extends Thread {    private boolean flag = false;    @Override
    public void run() {        int i = 0;
        System.out.println(Thread.currentThread().getName() + ":" +Thread.currentThread().isInterrupted());        while (!flag && !Thread.currentThread().isInterrupted()) {
            System.out.println(i++);            try {                synchronized (this) {                    if (i > 3) {                        //Thread.sleep(1000 * 60 * 60 * 24);
                        wait();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }    /**
     * 这里必须将需要中断的线程作为参数传过来
     * 用以进行中断
     * @param t(Thread)
     */
    public void cancel(Thread t) {
        System.out.println("ready stop currentThread...");
        flag = true;        //将需要中断的线程的中断标志位设置为true
        t.interrupt();
        System.out.println(t.getName() + ":" + t.isInterrupted());
    }    public static void main(String[] args) throws InterruptedException {
        SafeInterrupt safeInterrupt = new SafeInterrupt();
        safeInterrupt.start();
        Thread.sleep(100);
        safeInterrupt.cancel(safeInterrupt);
    }
}
不可中断的情况

好了,到现在我们已经可以安全的处理线程的中断了,但是还没完,因为不是所有的线程都是会响应中断的。比如IO的read()/write() 等就不会响应中断。而如果我们想不让其继续阻塞的话就需要我们手动的关闭底层的套接字。

public class CloseSocket extends Thread {    private Socket socket;    private InputStream in;

    public CloseSocket(Socket socket, InputStream in) {        this.socket = socket;        this.in = in;
    }    //重写中断方法 在中断线程时中断套接字
    @Override
    public void interrupt() {        try {            //关闭底层套接字
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {            //中断线程
            super.interrupt();
        }

    }
}

还有想死锁之类的不响应中断的情况用代码已经基本解决不了了,只能检查代码修改重启服务器啦。

原文出处:https://www.cnblogs.com/liyus/p/9975016.html  

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消