线程分为两部分:1、线程、线程池的创建
2、执行线程的创建
一、创建线程池
1、 Executors创建线程:使用Executors创建线程池可能会导致OOM(OutOfMemory ,内存溢出) 所以不建议使用,
原因底层确实是通过LinkedBlockingQueue实现的,LinkedBlockingQueue是一个用链表实现的有界阻塞队列,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE
// 创建线程池
ExecutorService pool = Executors.newFixedThreadPool(10);
// 关闭线程池
pool.shutdown();
2、 ThreadPoolExecutor : ArrayBlockingQueue有边界队列不会产生内存溢出。
private static ExecutorService executor = new ThreadPoolExecutor(10, 10,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(10));
3、开源类库,如apache和guava
guava:
<!--pom 依赖jar包 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>26.0-jre</version>
</dependency>
private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat("demo-pool-%d").build();
private static ExecutorService pool = new ThreadPoolExecutor(5, 200,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
pool.execute(new Thread(){
@Override
public void run(){
System.out.println(System.currentTimeMillis());
}
});
}
}
二、创建线程
需要返回值的实现Callable接口,使用Future来接收线程返回
不需要返回值的实现Runnable接口
package Thread;
import Thread.service.impl.CallableTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* 〈功能详细描述〉
*
* @author 2021/3/24
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
@Component
public class ThreadDemo {
private static ExecutorService executor = new ThreadPoolExecutor(10, 10,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(10));
public static void crawlRedisQueue() {
// 创建线程池,入参为int,表示线程池中线程数量
//ExecutorService pool = Executors.newFixedThreadPool(10);
for (int i = 0; i < 20; i++) {
//1、线程池执行
executor.execute(() -> {
System.out.println(Thread.currentThread().getName() + "======定时任务执行完成======");
});
//2、Callable操作有返回的线程
CallableTest callableTest = new CallableTest();
Future<Long> future = executor.submit(callableTest);
try {
System.out.println(future.get()+ executor.toString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
参考:https://blog.csdn.net/yan88888888888888888/article/details/83927609