1 同步容器类
有哪些同步容器。同步容器类包括Vector、Stack、HashTable和Collections.synchronizedXxx工厂方法创建的容器。
实现同步的方式。Vector、Stack、HashTable直接在方法上加synchronized关键字实现同步。Collections.synchronizedXxx通过定义一系列内部类SynchronizedXxx实现SynchronizedCollection类,在内部类中通过组合的方式,将不安全的list赋给内部final引用,并通过SynchronizedCollection的名为mutex的锁变量统一给每个方法加锁。
同步容器的缺点。(1)容器上的符合操作(迭代、条件运算)是非线程安全的,需要额外的客户端加锁机制。(2)同步容器将所有对容器状态的访问都串行化,以实现他们的线程安全性。这种方法的代价是严重降低并发性,当多个线程竞争容器的锁时,吞吐量将严重降低。
2 JUC包中并发容器有哪些
并发容器用来代替同步容器可以极大提高伸缩性并降低风险。
记忆:hash散列,Linked链表,Set不重复,Array数组,Deque双端,Block可阻塞……见名知意
3 运用生产者-消费者队列遍历所有文件
public class FileCrawler {
private static final int FILE_QUEUE_SIZE = 10;
private static final File DUMMY = new File("");
private static BlockingQueue<File> queue = new ArrayBlockingQueue<>(FILE_QUEUE_SIZE);
// 递归遍历目录,将所有文件放入队列
public static void enumerate(File directory) throws InterruptedException {
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
enumerate(file);
} else {
queue.put(file);
System.out.println("生产:" + file.getName());
}
}
}
public static void main(String[] args) {
try (Scanner in = new Scanner(System.in)) {
System.out.print("输入一个文件目录:");
String directory = in.nextLine();
// 生产者线程,从目录中搜索文件放入队列
Runnable enumerator = () -> {
try {
enumerate(new File(directory));
queue.put(DUMMY);
} catch (Exception e) {
}
};
new Thread(enumerator).start();
// 消费者线程,从队列中取出目录
Runnable searcher = () -> {
try {
boolean done = false;
while (!done) {
File file = queue.take();
System.out.println("消费:" + file.getName());
if (file == DUMMY) {
queue.put(file);
done = true;
}
}
} catch (Exception e) {
}
};
new Thread(searcher).start();
}
}
}
4 什么是串行线程封闭
自己的理解。 在JUC包中阻塞队列的同步机制使得能够安全的将对象从生产者线程发布到消费者线程,对象所有权由生产者转移到消费者,并且保证了线程的独占访问(对象开始被封闭在生产者线程,后来封闭到消费者线程),这种封闭机制就是串行线程封闭。
5 同步工具类
6 简单说一说FutureTask
FutureTask实现了Future,表示一种可生成结果的计算。FutureTask表示的计算时通过Callable来实现的,相当于一种可生成结果的Runnable,并且可以处于以下3中状态:等待运行,正在运行,运行完成。
Future.get的行为取决于任务的状态。如果任务已经完成,那么get会立即返回结果,否则get将阻塞直到任务进入完成状态,然后返回结果或者抛出异常。