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); } } 复制代码