基本概念
- Java的线程机制是抢占式的。调度机制会周期的中断线程,将上下文切换到另外一个线程, 从而为每个线程都提供时间片,使得每个线程都会分配到数量合理的时间去驱动它的任务。
- 线程状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING(超时等待)、TERMINATED。
- 阻塞(BLOCKED): 程序中的某个任务因为该程序之外的某些条件导致不能继续执行。
- 定义一个线程任务:实现Runable接口里面的
run()
,它是一个普通方法,要实现线程行为你需要new一个Thread通过start()
来初始化线程最终run()
才产生线程能力。还可实现Callable接口的call()
。 - 使用执行器(
java.util.concurrent.Executor
)管理Thread对象。// 创建线程池 线程数与所需数量相同 ExecutorService executorService = Executors.newCachedThreadPool(); // 创建一个有大小限制的线程池 ExecutorService exec = Executors.newFixdThreadPool(5); // 创建单线程池(创建线程数为1的FixedThreadPool) ExecutorService exec = Executors.newSingleThreadExecutor();
- 休眠。调用
sleep()
方法抛出InterruptedException
异常。 - 让步。调用Thread里面的
yield()
方法。 - 将线程转化为后台线程。调用
Thread
里面的setDaemon(true)
方法。 - 优先级, 在Thread类中定义了线程的三种优先级:
public static final int MIN_PRIORITY = 1; public static final int NORM_PRIORITY = 5; public static final int MAX_PRIORITY = 10;
- 从任务中返回值。Runable是执行工作的独立任务,不返回值。如需返回值需要使用Callable接口实现其
call()
方法,并且必须使用ExecutorService.submit()
方法调用它。
import java.util.ArrayList;
import java.util.concurrent.*;
/**
* @author : DKD
* @Project Name : demo
* @Package_Name : com.dkd.thread.concurrency
* @Description : 从线程中获取返回值,ExecutorService 的submit()方法会返回一个Future对象
* @Creation Date: 2018-10-02 16:36
* @ModificationHistory Who When What
* <p>
* ------------- --------------- --------------
*/
class TaskWithResult implements Callable<String> {
private int id;
public TaskWithResult(int id) {
this.id = id;
}
@Override
public String call() throws Exception {
return "result of TaskWithResult " + id;
}
}
public class CallableDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = new ArrayList<>();
for (int i = 0;i < 5; i++) {
results.add(executorService.submit(new TaskWithResult(i)));
}
for (Future<String> fs : results) {
try {
System.out.println(fs.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
executorService.shutdown();
}
}
}
}