// java8的函数式接口
@FunctionalInterface
public interface Runnable {
void run();
}
public
class Thread implements Runnable {
// 实现了Runnable接口,又聚合了一个Runnable实例
private Runnable target;
@Override
public void run() {
if (target != null) {
target.run();
}
}
}
Java 中的线程在运行的生命在周期中可能处于以下 6 个状态之一
thread-state 注意: 线程阻塞在进入 synchronized 关键字锁时的状态是阻塞状态, 而阻塞在 Lock 接口时的状态是等待状态.
public class Thread implements Runnable {
/* Whether or not the thread is a daemon thread. */
private boolean daemon = false;
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
public final boolean isDaemon() {
return daemon;
}
}
public class Thread implements Runnable {
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
// -- 将当前线程设为新建线程的父线程
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */
/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}
/* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
/*
* Do we have the required permissions?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();
this.group = g;
// -- 将daemon和priority属性设置为父线程对应属性
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
acc != null ? acc : AccessController.getContext();
this.target = target;
setPriority(priority);
// -- 将父线程的inheritableThreadLocals复制过来
if (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
// -- 分配线程ID
/* Set thread ID */
tid = nextThreadID();
}
}
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
问题引入: 锁(synchronized)的互斥机制同步了线程之间的行为,解决了线程之间相互干涉的问题, 但是没有解决线程之间的协作问题(比如某些部分的工作必须在其他部分被解决之前解决). 本质问题是如何实现:一个线程(生产者)修改了一个对象的值(完成某些工作),而让另一个线程(消费者)感知到变化. 简单的实现方法是让消费者线程
// 简单的实现: 让消费者线程不断循环检查变量是否符合预期
synchronized (syncObject) {
while (value != desire) {
Thread.sleep(1000);
}
// doSomething()
}
以上实现存在如下问题:
以上问题能够使用 Java 内置的等待-通知机制解决,此机制的使用方法定义在基类 Object 上, 相关方法如下:
为什么以上等待-通知机制的方法放在 Object 中?
例子:WaitNotify 使用细节
对应的伪代码如下
// waiting thread
synchronized (syncObject) {
while (value != desire) {
syncObject.wait();
}
// do something
}
// notify thread
synchronized (syncObject){
// change value
syncObject.notifyAll();
}
/**
* join方法会对线程对象本身上锁
* @param millis 最长等待时间
*/
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
// 父类Object上的方法,参数0表示没有超时时间
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
// 父类Object上的方法,参数delay为超时时间
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
public final void join() throws InterruptedException {
join(0);
}