1、Java多线程实现
A.继承Thread类,重写run方法
@Test
public void threadTest() {
Thread thread = new myThread();
thread.start();
}
public class myThread extends Thread {
@Override
public void run(){
System.out.println("Thread create");
}
}
通过继承Thread 重写run方法,其中run()方法的方法体代表了线程需要完成的任务,称之为线程执行体。通过调用线程对象引用的start()方法,使得该线程进入到就绪状态。
B.实现Runnable接口,重写run方法。
@Test
public void runnableTest() {
Runnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
}
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("MyRunnable create");
}
}
创建Runnable实现类的实例,并以此实例作为Thread类的target来创建Thread对象,该Thread对象才是真正的线程对象。
C.通过Callable和FutureTask创建线程
@Test
public void callableTest() throws ExecutionException, InterruptedException {
Callable<Integer> myCallable = new MyCallable(); // 创建MyCallable对象
FutureTask<Integer> ft = new FutureTask<Integer>(myCallable);
Thread thread = new Thread(ft);
thread.start();
int result = ft.get();//当前是阻塞
}
public class MyCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("MyCallable create");
return 0;
}
}
在实现Callable接口中,此时不再是run()方法了,而是call()方法,此call()方法作为线程执行体,同时还具有返回值!在创建新的线程时,是通过FutureTask来包装MyCallable对象,同时作为了Thread对象的target。
D.通过线程池创建线程
Executors类:提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口
I.newSingleThreadExecutor
创建一个单线程化的Executor
@Test
public void executeSingleTest() {
Runnable runnable = new MyRunnable();
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(runnable);
}
II.newCachedThreadPool
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
@Test
public void executeCacheTest() {
Runnable runnable = new MyRunnable();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(runnable);
}
III.newScheduledThreadPool
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。
@Test
public void executeScheduledTest() {
Runnable runnable = new MyRunnable();
ExecutorService executorService = Executors.newScheduledThreadPool(10);
executorService.submit(runnable);
}
IIII.newFixedThreadPool
创建固定数目线程的线程池。
@Test
public void executeFixedTest() {
Runnable runnable = new MyRunnable();
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.submit(runnable);
}
2、CompletableFuture 异步并发
JAVA8 CompletableFuture能够将回调放到与任务不同的线程中执行,也能将回调作为继续执行的同步函数,在与任务相同的线程中执行。它避免了传统回调最大的问题,那就是能够将控制流分离到不同的事件处理器中。
@Test
public void completableFutureTest() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(100);
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(()->{
System.out.println("查询图片");
return "image_path";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
System.out.println("查询商品");
return "product";
});
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(()->{
System.out.println("查询SKU");
return "SKU";
});
//等待所有的运行完成,返回
CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
allOf.get();
//任何一个执行完成,返回
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2, future3);
anyOf.get();
}
详细使用参考文档:https://www.jianshu.com/p/dff9063e1ab6