Java线程相关方法

Java线程相关方法

1. sleep

  • public static native void sleep(long millis) throws InterruptedException

当millis小于0的时候抛出IllegalArgumentException,当该线程被中断时,抛出InterruptedException

  • public static void sleep(long millis, int nanos) throws InterruptedException

当millis小于0,或者nanos不在0 ~ 999999范围内的时候抛出IllegalArgumentException,当该线程被中断时,抛出InterruptedException

该方法使当前线程暂时停止运行,但是它并不释放对象锁。也就是说如果有synchronized同步方法,或同步块,其它线程仍然不能访问加锁的代码。

public class Main {

    public static void main(String[] args)  {
        Thread t = new Thread(new FiveSecondSleepRunnable());
        t.start();
        //t.interrupt();
    }

    private static class FiveSecondSleepRunnable implements Runnable{
        @Override
        public void run() {
            try {
                StopWatch stopWatch = new StopWatch();
                stopWatch.start();

                Thread.sleep(5000);

                stopWatch.stop();
                System.out.println("Sleep " + stopWatch.getTime() + " millisecond");
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("I am interrupted");
            }
        }
    }
}

结果如下:
1.png

当线程t被其它线程中断时, 即注释的代码t.interrupt();启用时,会抛出异常,结果如下:

2.png

2.join

  • public final synchronized void join(long millis) throws InterruptedException
  • public final synchronized void join(long millis, int nanos) throw InterruptedException
  • public final void join() throws InterruptedException

当一个线程调用join方法,其它线程要等待该线程到时间结束,或者到该线程生命结束。

public class Example {

    public static void main(String[] args) {
        Thread t1 = new Thread(new MyRunnable(), "t1");
        Thread t2 = new Thread(new MyRunnable(), "t2");
        Thread t3 = new Thread(new MyRunnable(), "t3");

        t1.start();

        //start second thread after waiting for 2 seconds or if it's dead
        try {
            t1.join(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t2.start();

        //start third thread only when first thread is dead
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t3.start();

        //let all threads finish execution before finishing main thread
        try {
            t1.join();
            t2.join();
            t3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("All threads are dead, exiting main thread");
    }
}

class MyRunnable implements Runnable{

    @Override
    public void run() {
        System.out.println("Thread started:::"+Thread.currentThread().getName());
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread ended:::"+Thread.currentThread().getName());
    }
}

如上代码,t2线程要等待t1线程执行2000毫秒后才会执行,t3线程要等到t1线程执行结束才能执行。主线程要等到t1,t2,t3线程都结束时才会打印出All threads are dead, exiting main thread。结果如下

3.png

3.yield

public static native void yield()

该方法暗示调度器,线程自己放弃当前对处理器的使用权,但是这只是一个暗示,调度器可以忽视。yield和sleep的区别在于,sleep不管线程池中是否有可运行状态的线程,都会使线程进入TIMED_WAITING状态并且至少会等待超时时间到达后才会再次执行。而yield则是线程放弃自己对处理器的使用权,进入RUNNABLE状态,若此时没有线程使用处理器,那么它又会进入RUNNING状态。

4.interrupt

public void interrupt()

该方法并不是真正地去中断目标线程,而是设置目标线程的中断状态/标志,至于如何去响应这个中断,则是由编程人员来决定。

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread’s interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread’s interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector’s wakeup method were invoked.

If none of the previous conditions hold then this thread’s interrupt status will be set.

前三种情形其实是描述了如果线程处于等待状态或是阻塞在某一种资源上,那么 interrupt() 方法会使得线程跳出这种状态继续执行下去。第四种情形则描述了如果线程正在正常执行,那么 interrupt() 的效果则是设置了线程的中断状态,至于怎么处理这种状态,可以选择忽略也可以按需处理。

某些API有中断处理,如

  • Object.wait()/Thread.sleep()
  • 大部分java.util.concurrent包里的类
  • Java NIO,但是不是使用InterruptedException,而是使用ClosedByInterruptException

对于这些Api,我们可以在try-catch中对中断做出处理,如

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new MyThread();

        thread.start();

        TimeUnit.SECONDS.sleep(5);

        thread.interrupt();
    }
}

class MyThread extends Thread {
    public void run() {
        System.out.println("Sleeppppppppppp");

        try {
            TimeUnit.SECONDS.sleep(100);
            System.out.println("Awakeeeeeeeee");
        } catch (InterruptedException e) {
            System.out.println("I am interrupted");
        }
    }
}

MyThread线程sleep 100秒,主线程在运行5秒之后中断MyThread。在try-catch块中,我们进入处理,输入I am interrupted。结果如图,首先输出Sleeppppppppppp,但是并没有来得及输出Awakeeeeeeeee就中断了。

4.png

而对于没有中断处理的情况,就需要我们自己判断线程中断状态,作出相应处理。如下,修改MyThread类,main函数不变。我们在while循环中做业务处理,但是因为是无线循环,我们需要判断中断状态,如果线程被中断,我们就跳出循环。

class MyThread extends Thread {
    public void run() {
        while (true) {
            // Do what you what-does-java-lang-thread-interrupt-do
            // ...
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("I am interrupted");
                break;
            }
        }
        System.out.println("Thread exit");
    }
}

结果如下图,通过判断线程中断状态来结束线程。

5.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容