- 使用线程
class MyRunnable implements Runnable { @Override public void run() { // TODO } } public class Main { public static void main(String[] args) { /** * 实现runnable接口. */ Runnable r = new MyRunnable(); /** * 由Runnable接口创建Thread对象. */ Thread t = new Thread(r); /** * 启动线程. */ t.start(); } }
- 线程状态
- 新生线程:该线程还没有开始运行。
- 可运行线程:一旦调用start方法,线程就处于可运行状态。一个可运行的线程可能正在运行也可能没有运行,这取决于操作系统给线程提供的运行时间。
- 被阻塞的线程:当线程试图获取一个内部的对象锁,但是该锁被其他线程持有。
- 等待线程:线程等待另一个线程通知调度器一个条件时,进入等待状态。
- 被终止的线程:由于run方法的正常退出而自然死亡,或者由于没有捕获的异常终止了run方法而意外死亡。
- 终止线程
interrupt方法可以用来请求终止线程。当对一个线程调用interrupt方法时,线程的中断状态将被置位。如果线程被阻塞,就无法检测中断状态,会抛出InterruptedException。interrupted方法是一个静态方法,检测当前的线程是否被中断,并且会清楚该线程的中断状态。isinterrupted方法是一个实例方法,检测是否有线程被中断。
- 锁对象
Lock lock = new ReentrantLock(); lock.lock(); try { // TODO } finally { lock.unlock(); }
- 条件对象
线程进入临界区,却发现在某一条件满足之后它才能执行。要使用一个条件对象来管理已经获得了一个锁但是却不能执行的线程。
Condition new Condition():返回一个与该锁相关的条件对象。
void await():将该线程放到条件的等待集合中。
void signalAll():解除该条件的等待集中的所有线程的阻塞状态。
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Main { private Lock lock; private Condition condition; public Main() { lock = new ReentrantLock(); condition = lock.newCondition(); } public void test() throws InterruptedException { // TODO lock.lock(); try { // TODO while (/*some conditions*/) { condition.await(); } // TODO condition.signalAll(); } finally { lock.unlock(); } } }
- synchronized关键字
Java中的每个对象都有一个内部锁,每个锁有一个内部条件。由锁来管理那些试图进入synchronized方法的线程,由条件来管理那些调用wait的线程。public class Main { public void test() throws InterruptedException { // TODO synchronized (Main.class) { // TODO while (/*some conditions*/) { wait(); } // TODO notifyAll(); } } }
- Volatile域
volatile关键字为实例域的同步访问提供了一种免锁机制。
- 读/写锁
如果很多线程从一个数据结构中读取数据,而很少修改其中的数据,ReentrantReadWriteLock类是非常实用的。import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Main { private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private Lock readLock = rwl.readLock(); private Lock writeLock = rwl.writeLock(); private int val; public int getVal() { readLock.lock(); try { } finally { readLock.unlock(); } return val; } public void setVal(int val) { writeLock.lock(); try { this.val = val; } finally { writeLock.unlock(); } } }
- Callable与Future
Callable与Runnable类似,但是有返回值。
Future保存异步计算的结果。
FutureTask包装器可将Callable转换成Future和Runnable。
Callable<Integer> myComputation = ...; FutureTask<Integer> task = new FutureTask<Integer>(myComputation); Thread t = new Thread(task); t.start(); // TODO Integer result = task.get();
- 线程池
调用Executors类中的静态方法newCachedThreadPool或newFixedThreadPool。调用submit提交Runnable或Callable对象。不再提交任何任务时,调用shutdown。