Java多线程基础之常用方法

sleep方法

这方法理解起来简单,使用也简单。作用是让当前线程休眠指定的时间,也就是暂停当前线程。sleep方法是个Thread类的静态方法,可以在任意的地方执行。

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

进入源码看看这方法,有一个native关键字,这关键字是jni(Java Native Interface 实现Java层与C/C++层之间的通讯)标识,这里不多讲述。使用这sleep方法要自行抛出异常。这方法通常用于延迟执行代码。
比如。

    try{
        Thread.sleep(2000);
        //2秒后执行的代码
    }catch(InterruptedException e){
    }

或者作为定时器

    while(true){
        try{
            Thread.sleep(2000);
            //每2秒后执行的代码
        }catch(InterruptedException e){
        }
    }

wait、notify方法

这两个方法其实是一对的,从名字来看一个等待,一个唤醒。上面提到的sleep方法是自动唤醒自己,而wait是一直等待,等着notify唤醒。进入源码,查看这两个方法,会发现这两个方法并不是Thread类的,而是Object类的方法。而且都是用native关键字修饰,意味着这也是jni通信。

    class Object {
    public final native void wait(long timeout) throws InterruptedException;

    public final native void notify();    
    ...
    }

这两个方法主要是用于线程的锁。之前说过锁可以是任意对象,所以wait、notify方法就是锁的方法。官方API文档描述notify方法是唤醒在此对象监视器(锁)上等待的单个线程,wait方法在其他线程调用此对象的 notify方法,导致当前线程等待。还有一个notifyAll方法,意思是notify方法等待的所有线程。
用例子说话。

    final Object obj = new Object();
    new Thread() {
        public void run() {
            synchronized (obj) {
                System.out.println("wait before");
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                }
                System.out.println("wait after");
            }
        }
    }.start();
    try {
        Thread.sleep(1000);
        System.out.println("延迟1秒");
        synchronized (obj) {
            obj.notify();
        }
    } catch (InterruptedException e) {
    }

输出为

wait before
延迟1wait after

使用这两个方法要注意的是监视器(锁)必须是一致,而且要synchronized同步。否则抛出IllegalMonitorStateException。

interrupt方法

上一节讲到,线程阻塞而无法执行下面代码,这是就要用到interrupt方法。

        Thread thread = new Thread() {
            public void run() {
                try {
                    obj.sleep(10000);//可以用wait代替,但是别忘了同步锁
                } catch (InterruptedException e) {
                }
                System.out.println("go");
            }
        };
        thread.start();
        thread.interrupt();

原来要等待10秒执行打印,使用interrupt就可以清除阻塞。

join方法

join方法是等待该线程终止,意味着不往下面语句执行,直接中断。从源码上分析,其实是wait方法,一直阻塞。

    public void join(){
        ...
         while (isAlive()) {
             wait(0);
         }
         ...
    }

来个例子。

    Thread thread1 = new Thread() {
        public void run() {
            try {
                Thread.sleep(1000);
                System.out.println("1 run before");
                join();//执行上面的语句就永久睡眠
                System.out.println("1 run");//不再执行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    thread1.start();//thread1先执行

    Thread thread2 = new Thread() {
        public void run() {
            try {
                Thread.sleep(5000);//延迟5秒打印
                System.out.println("2 run");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    try {
        Thread.sleep(1000);//thread2延迟1秒启动
        thread2.start();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

上面的例子是thread1线程执行比thread2线程要先,thread1会完成join方法之前的语句,不再执行join方法后面的语句。其实可以把join方法当作一直不醒的wait方法。

yield方法

yieId方法作用是暂停当前正在执行的线程对象,并执行其他线程。yieId与join方法区别在于是否还往下执行语句。yieId不带任何参数,而且暂停的触发时间不准确。

Java多线程基础系列就讲到这里。作者初写文章,写作能力还待提升,谢谢大家~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值