您的位置:首页 > 编程语言 > Java开发

Java多线程基础之常用方法

2017-03-20 00:07 260 查看

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 (ob
4000
j) {
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
延迟1秒
wait 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多线程基础系列就讲到这里。作者初写文章,写作能力还待提升,谢谢大家~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: