Java 并发编程
根据《java核心技术第一卷》和JDK 1.6源代码整理而成
一、Runnable和Thread
1、《核心技术》中,不要调用Thread类和Runnable对象的run方法。直接调用run方法,只会执行同一个线程中的任务,不会启动新的线程。
首先,Runnable接口只定义了一个方法。
public interface Runnable { <span style="white-space:pre"> </span>public abstract void run(); }
在Thread类中,也有一个run方法,它只执行Runnable对象的run方法,并没有启动新线程:
/* What will be run. */ private Runnable target; public void run() { if (target != null) { target.run(); } }
从代码中不难看出,执行run方法并没有意义。
《核心技术》中又说,应该调用Thread.start方法,该方法将会创建一个执行run方法的新线程。同样看源代码:
/* The group of this thread */ private ThreadGroup group; 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 || this != me) throw new IllegalThreadStateException(); group.add(this); start0(); if (stopBeforeStart) { stop0(throwableFromStop); } } private native void start0();
可以看出,start方法会调用本地方法start0。而start0会创建一个新的线程,执行run方法。
2、线程状态
在Thread类中定义了枚举State{New, Runnable, Blocked, Waiting, TIMED_WAITING, TERMINATED},共六种。
二、同步
1、Lock和Condition
它们都是java.util.concurrent.locks包里的接口,Lock的newCondition()方法会生成一个Condition对象。
在Condition接口中定义了await(), singal(), signalAll()方法,是为了与Object类中的wait(), notify(), notifyAll()不发生冲突。
2、synchronized
Java中的每一个对象都有一个内部锁。如果一个方法用synchronized关键字声明,那么对象锁将保护整个方法。也就是说,要调用该方法,必须获得内部的对象锁。
换句话说,
public synchronized void method() { method body; }
等价于:
public void method { this.intrinsicLock.lock() try { method body; } finally { this.intrinsicLock.unlock(); } }
内部对象锁只有一个相关条件。wait方法添加一个线程到等待级中,notifyAll/notify方法解除等待线程的阻塞状态。
三、LinkedBlockingQueue
线程阻塞队列
四、Callable和Future
1、Callable类似于Runnable,但是它有返回值;
2、而Future可以保存异步计算的结果。
五、Executors和Executor、ExecutorService以及ThreadPoolExecutor
1、Executor是一个接口,其只有一个方法:
public interface Executor { void execute(Runnable command); }
ExecutorService本身也是一个接口,其扩展了Executor。其又增加了submit、invokeAll、invokeAny方法。也就是“将任务提交给执行者”和“让执行者执行任务”的方法。
而AbstractExecutorService是一个抽象类,实现了ExecutorService接口,将其中的通用方法提供了一个实现。
2、ThreadPoolExecutor是一个具体的线程池类,也就是常说的“线程池”,它继承了AbstractExecutorService。作为一个具体类,其实现了execute方法。
3、Executors是执行器的工厂类。
六、同步器