Thread相关知识点整理

Posted by 程序亦非猿 on 2015-10-20

Thread

多线程,举足轻重,记录整理部分相关的重要的知识点,后续应该还需要再学习一下Runnable,线程池.

后面有提到monitor,翻译为 监视器

线程的状态图/生命周期图:
Thread-LifeCycle

Thread.sleep()

静态方法,即作用于当前线程

睡眠,睡眠当前线程,睡眠后回到可执行状态,所以并不一定睡眠过会立马执行后面的代码,或许休眠这词更好.

PS:sleep,锁并没有被释放

Thread.yield();

yield()是个静态方法.
Thinking in java 的解释如下:
线程调度器 的一种建议,它在声明:”我已经执行完生命周期中最重要的部分了,此刻正是切换给其他任务执行一段时间的大好时机”
线程调度器(Java线程机制的一部分,可以将CPU从一个线程转移给另一个线程)

其他理解:
让当前线程回到可执行状态,以便让具有相同优先级的线程进入执行状态,但不是绝对的。因为虚拟机可能会让该线程重新进入执行状态。

简单理解就是我重要的事干完了,我可以让出cpu给其他线程(相同优先级).

补充:锁也没有被释放

wait)

看下Java文档怎么说:

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
In other words, this method behaves exactly as if it simply performs the call wait(0).

The current thread must own this object’s monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object’s monitor to wake up either through a call to the notify method or the notifyAll method.

The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
This method should only be called by a thread that is the owner of this object’s monitor.

  1. 当前线程必须拥有这个对象的monitor,当前线程会释放该monitor的拥有权,并且等到别的线程(正在等待这个对象的monitor)调用notify或者notifyAll来唤醒它.
  2. wait方法应该被用于一个循环里.
  3. 必须拥有该对象的monitor,否则会报错–IllegalMonitorStateException

补充: wait会释放锁

实例,HandlerThread:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Looper getLooper() {
if (!isAlive()) {
return null;
}
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}

IllegalMonitorStateException例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static final Object lock = new Object()
private boolean open = false;
public int test() {
synchronized (lock) { //这样会报错
while (!open) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return 1;
}

报错日志:

1
2
3
4
5
6
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at com.example.concurrent.WaitNotify.test(WaitNotify.java:64)
at com.example.concurrent.WaitNotify$1.run(WaitNotify.java:81)
at java.lang.Thread.run(Thread.java:745)

notify,notifyAll

notify)

Wakes up a single thread that is waiting on this object’s monitor.
If any threads are waiting on this object, one of them is chosen to be awakened.
The choice is arbitrary and occurs at the discretion of the implementation.
A thread waits on an object’s monitor by calling one of the wait methods.
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.
The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object;
for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.

This method should only be called by a thread that is the owner of this object’s monitor. A thread becomes the owner of the object’s monitor in one of three ways:

  1. By executing a synchronized instance method of that object.
  2. By executing the body of a synchronized statement that synchronizes on the object.
  3. For objects of type Class, by executing a synchronized static method of that class.

Only one thread at a time can own an object’s monitor.

理解:

  1. 唤醒一个等待这个对象的monitor的线程
  2. 这个选择是随意的
  3. 这个被唤醒的线程不能执行直到当前线程交出对象锁
  4. 这个机会是需要线程去争取的
  5. 这个方法跟前面的wait一样,也需要拥有这个对象的monitor

一个线程可以有三种方法拿到对象的monitor:

  1. 正在执行该对象的同步方法
  2. 正在执行锁住该对象的同步块(synchronized 代码块)
  3. 正在执行锁住该的静态方法

notifyAll

跟notify作用一样,当时notify唤醒的只是一个线程,而notifyAll唤醒的是所有.

Android中线程的比较:

对比

补充

线程除了用户线程外还有一种叫做守护线程,可以通过setDaemon(boolean isDaemon)来设置

守护线程和用户线程的区别在于:
守护线程依赖于创建它的线程,而用户线程则不依赖

举个简单的例子:
如果在main线程中创建了一个守护线程,当main方法运行完毕之后,守护线程也会随着消亡,而用户线程则不会,用户线程会一直运行直到其运行完毕。
不过一般我们也不会用到守护线程.

资料

  1. Thinking in Java
  2. Object
  3. Thread