class RunnableDemo implements Runnable {
private String threadName;
private RunnableDemo(String name) {
this.threadName = name;
System.out.println("creating thread:" + threadName);
}
@Override
public void run() {
System.out.println("Running " + threadName);
try {
for (int i = 0; i < 10; i++) {
System.out.println("Thread:" + threadName + "," + i);
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + "interrupter");
}
System.out.println("Thread " + threadName + " exiting");
}
// run
public static void main(String[] args) {
RunnableDemo r = new RunnableDemo("MyThread");
r.run();
}
}
复制代码
public class ThreadDemo extends Thread {
@Override
public void run() {
System.out.println("thread" + Thread.currentThread().getId() + " running...");
}
// run 10 thread
public static void main(String[] args) throws InterruptedException {
ThreadDemo[] threadDemos = new ThreadDemo[10];
for (int i = 0; i < threadDemos.length; i++) {
threadDemos[i] = new ThreadDemo();
}
for (ThreadDemo threadDemo : threadDemos) {
threadDemo.start();
}
// wait other thread complete
for (ThreadDemo threadDemo : threadDemos) {
threadDemo.join();
}
System.out.println("completing");
}
}
复制代码
通过 FutureTask 包装一个 Callable 的实例,再通过 Thread 包装 FutureTask 的实例,然后调用 Thread 的 start() 方法
public class CallableDemo implements Callable {
@Override
public String call() throws Exception {
return "yo!";
}
@Test
public void callUse() throws Exception {
CallableDemo callableDemo = new CallableDemo();
System.out.println(callableDemo.call());
}
@Test
public void threadUse() throws ExecutionException, InterruptedException {
FutureTask futureTask= new FutureTask<>(new CallableDemo());
Thread thread=new Thread(futureTask);
thread.start();
System.out.println(futureTask.get());
}
}
复制代码
FutureTask继承关系
一般通过ThreadPoolExecutor类来创建线程
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
)
复制代码
corePoolSize 线程池的基本大小
maximumPoolSize 线程池的最大大小
keepAliveTime 空闲线程(超出基本大小的线程)的存活时间
unit 空闲线程存活时间的单位(毫秒,秒...)
workQueue 任务队列,提交的任务的阻塞队列( BlockingQueue )。more: Java多线程 - 阻塞队列详解
threadFactory 线程工产,线程的创建策略,有默认实现,可以通过定制线程工厂来监听线程信息
handler 饱和策略,当线程由于任务队列满了,或者某个任务被提交到一个已被关闭的线程的处理方式
AbortPolicy 中止策略, 默认策略 ,该策略会抛出RejectExecutionException异常,调用者可以根据这个异常编写自己的处理代码
DiscardRunsPolicy 抛弃策略,悄悄抛弃该任务,不抛异常
DiscardOldestPolicy 抛弃最久任务策略 将工作队列中最老的(也就是下一个要执行的)任务抛弃。 优先队列将会是优先级最高的
CallerRunsPolicy 调用者执行策略,将线程添加到添加工作队列的线程去执行
ps: 构造器参考下表
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool=Executors.newFixedThreadPool(2);
pool.execute(() -> System.out.println("yo!"));
pool.shutdown();
}
复制代码
通过调用submit方法
在 ExecutorService 中提供了重载的 submit() 方法,该方法既可以接收 Runnable 实例又能接收 Callable 实例。对于实现 Callable 接口的类,需要覆写 call() 方法,并且只能通过 ExecutorService 的 submit() 方法来启动 call() 方法
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool=Executors.newFixedThreadPool(2);
Future future=pool.submit(() -> {
Thread.sleep(100);
return "yo!";
});
System.out.println(future.get());
pool.shutdown();
}
复制代码
定义:延时任务("在100ms后执行的任务") 周期任务("每10ms执行一次的任务")
使用:通过new ScheduledThreadPoolExector()对象
Demo:
public class ScheduleExecutorDemo implements Runnable {
private String name;
public ScheduleExecutorDemo(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " 运行");
}
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService1 = Executors.newScheduledThreadPool(2);
// after 10s run
executorService1.schedule(new ScheduleExecutorDemo("task1"), 10, TimeUnit.SECONDS);
executorService1.shutdown();
ScheduledExecutorService executorService2 = Executors.newScheduledThreadPool(2);
// run per 1s
executorService2.scheduleAtFixedRate(new ScheduleExecutorDemo("task1"),
0, 1, TimeUnit.SECONDS);
// run per 2s
executorService2.scheduleWithFixedDelay(new ScheduleExecutorDemo("task2"),
0, 2, TimeUnit.SECONDS);
}
}
复制代码