1 | Thread implements Runnable: |
run()
- run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
- 调用start方法方可启动线程,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由jvm的内存机制规定的。
- run()方法必须是public访问权限,返回值类型为void.。
start()
- 用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。
- 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。
- 方法 run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
join()
- Java Thread中, join() 方法主要是让调用改方法的thread完成run方法里面的东西后, 在执行join()方法后面的代码。
- 使用场景: 主线程开启子线程,子线程进行网络访问,然后获得结果,填充数据至UI。
- 线程同步,除了join()方法外,目前安卓中还有另外一个Handler,Message
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
//完成主界面更新,拿到数据
String data = (String)msg.obj;
updateWeather();
textView.setText(data);
break;
default:
break;
}
}
};
在子线程中,通过传递Message对象给handler处理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17private void updateWeather() {
new Thread(new Runnable(){
public void run() {
//耗时操作,完成之后发送消息给Handler,完成UI更新;
mHandler.sendEmptyMessage(0);
//需要数据传递,用下面方法;
Message msg =new Message();
msg.obj = "数据";//可以是基本类型,可以是对象,可以是List、map等;
mHandler.sendMessage(msg);
}
}).start();
}
sleep()
sleep是让线程指定休眠时间,然后继续工作
yield()
yiedld这个方法是让当前线程回到可执行状态,以便让具有相同优先级的线程进入执行状态,但不是绝对的。因为虚拟机可能会让该线程重新进入执行状态。
wait()
wait是等待,直到有线程通知notify()唤醒他才会重新工作。
sleep与wait的区别:
- sleep是你困了,要睡觉,等你睡醒了再干活。
- wait是你现在没事做,先眯会儿吧,什么时候领导提醒你该干活了再干。
简单点说wait和sleep的区别:
- wait只能在有线程锁的部分调用,而sleep不需要。
- wait是睡眠时放开线程锁,此时线程不占用任何资源,不增加时间限制。而sleep睡眠时占着线程锁占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源(同步资源)被占用,其他线程无法进入,会增加时间限制。
- wait需要notify方法来唤醒,而sleep是定时醒。
notify()
Wait()和notify():如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。
一般用在synchronized机制中1
2
3
4
5
6
7
8例如:
线程A
synchronized(obj) {
while(!condition) {
obj.wait();
}
obj.doSomething();
}
当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。
在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:
1 | 线程B |
需要注意的概念是:
- 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {……} 代码段内。
- 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {……} 代码段内唤醒A.
- 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
- 如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
- obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
- 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。
interrupted()
- interrupt:置线程的中断状态
- isInterrupt:线程是否中断
- interrupted:返回线程的上次的中断状态,并清除中断状态