1. JUC(java.util.concurrent)的常见类
1)Callable 接口
我们之前学过 Runnable 接口,它是一个任务,可以在创建线程的时候把任务丢给线程使用匿名内部类等方法来完成创建对象。现在我们有了一个新的方法来创建任务并执行这个任务,就是 Callable 接口。
Runnable 的 run 方法是没有返回值的,但是 Callable 提供了返回值,支持泛型,我们就能获取到我们想要的参数。
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return null;
}
};
我们使用匿名内部类的方法创建一个 Callable 对象,并且重写 call 方法,就相当于重写 Runnable 的 run 方法。我们是不能把这个对象直接放到线程的构造方法中的,因为 Thread 没有提供传入 Callable 的版本。我们要使用另一个类 FutureTask 来拿到结果,在把创建的 futureTask 对象放到线程创建时的构造方法中去。
FutureTask<Integer> task = new FutureTask<>(callable);
Thread t1 = new Thread(task);
t1.start();
System.out.println(task.get());
这里的 task.get 方法会阻塞 main 线程结束,直到 t1 线程正确计算出结果。
2)ReentrantLock
这是早期的锁实现,现在有更智能、更好的替代 synchronized,那我们还学它干嘛呢?它还活着就一定是有原因的。
- synchronized 是关键字,是由 JVM 内部通过 C++ 实现的,而 ReentrantLock 是一个类。
- synchronized 是通过进出代码块来实现的,ReentrantLock 需要 Lock 和 Unlock 方法来辅助。
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
a++;
reentrantLock.unlock();
- ReentrantLock 除了提供 Lock 和 unlock 之外还提供了一个不会造成阻塞的 tryLock()。它会根据是否加锁成功返回 true 或者 false。
- synchronized 是非公平锁,而 ReentrantLock 默认是非公平锁,但是也提供了公平锁的实现。
- ReentrantLock 的等待通知机制是 Condition 类,比 synchronized 的 wait 和 notify 功能更强。
3)线程池
我们先来简单的版本。
public class {
{
() {
{
( ; i < ; i++) {
System.out.println();
}
}
};
Executors.newFixedThreadPool();
executorService.shutdown();
}
}




