多线程理论相关可直接上https://www.runoob.com/java/java-multithreading.html查看
代码如下:
main方法执行时将其他同名函数改名
package com;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;
/**
* @ClassName ThreadPoolExecutorTest
* @Description 多线程+线程池学习
* @Author
* @Data 2019/6/13
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ThreadPoolExecutorTest {
//多线程使用,集成Thead并重写run方法
//执行结果
// 我是第一个子线程0
// 我是第一个子线程1
// 我是第一个子线程2
// 我是第一个子线程3
// 我是第一个子线程4
// 我是第二个子线程0
// 我是第二个子线程1
// 我是第二个子线程2
// 我是第二个子线程3
// 我是第二个子线程4
public static void main4(String[] args) throws InterruptedException {
//多线程编程之机场Thread类执行
class ExtendThread extends Thread{
private String task;
public ExtendThread(String task){
this.task = task;
}
//集成Thread类并重写run方法
@Override
public void run(){
for(int i=0; i<5; i++){
System.out.println(task+i);
}
}
}
ExtendThread extendThread = new ExtendThread("我是第一个子线程");
ExtendThread extendThread1 = new ExtendThread("我是第二个子线程");
extendThread1.start();
extendThread.start();
}
//通过实现 Runnable 接口来创建线程
//执行结果
// 我是子线程0
// 我是子线程1
// 我是子线程2
// 我是主线程
public static void main5(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
for(int i=0; i<3; i++){
System.out.println("我是子线程" + i);
}
}
}).start();
Thread.sleep(1000);//延迟一秒执行
System.out.println("我是主线程");
}
//通过 Callable 和 Future 创建线程
//创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
//创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值
//使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
//调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
//执行结果
// 我是返回值
public static void main6(String[] args) throws ExecutionException, InterruptedException {
class Call implements Callable{
@Override
public String call() throws Exception {
return "我是返回值";
}
}
//使用FutureTask来执行任务,task.get()获取值
FutureTask task = new FutureTask(new Call());
new Thread(task).start();
System.out.println(task.get());
}
// Callable 和 Future接口的区别
//(1)Callable规定的方法是call(),而Runnable规定的方法是run().
//(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
//(3)call()方法可抛出异常,而run()方法是不能抛出异常的。
//(4)运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。
// 它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
// 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
// Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
// Executors.newCacheThreadPool():可缓存线程池,
// 先查看池中有没有以前建立的线程,如果有,就直接使用。如果没有,就建一个新的线程加入池中,缓存型池子通常用于执行一些生存期很短的异步型任务
// 执行结果,线程池为无限大,当执行当前任务时上一个任务已经完成,会复用执行上一个任务的线程,而不用每次新建线程
// excute与submit的区别在于是否有返回值,excute无返回值,submit返回值被包装在Future中
// pool-1-thread-1正在被执行
// 返回值0
// pool-1-thread-1正在被执行
// 返回值1
// pool-1-thread-2正在被执行
// 返回值2
// pool-1-thread-1正在被执行
// 返回值3
// pool-1-thread-1正在被执行
// 返回值4
@Test
public void cachedThreadPool() throws ExecutionException, InterruptedException {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
final int index = i;
//execute无返回值 Runnable无返回值
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在被执行");
}
});
//submit有返回值 Callable有返回值
Future a = cachedThreadPool.submit(new Callable() {
@Override
public String call() throws Exception {
return "返回值"+index;
}
});
System.out.println(a.get());
}
}
//Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。
//执行结果
// pool-1-thread-1正在执行
// pool-1-thread-3正在执行
// pool-1-thread-2正在执行
// pool-1-thread-1正在执行
// pool-1-thread-3正在执行
// pool-1-thread-2正在执行
// pool-1-thread-1正在执行
// pool-1-thread-2正在执行
// pool-1-thread-3正在执行
// pool-1-thread-1正在执行
//因为线程池大小为3,每个任务输出打印结果后sleep 1秒,所以每秒打印3个结果。
//定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()
public static void main1(String[] args){
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for(int i=0;i<10;i++){
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try{
System.out.println(Thread.currentThread().getName()+"正在执行");
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
});
}
}
//Executors.newScheduledThreadPool(int n):创建一个定长线程池,支持定时及周期性任务执行
//执行结果
// 系统时间2019-06-13 11:41:51
// 执行时间12019-06-13 11:41:52
// 延迟1秒执行
// 执行时间22019-06-13 11:41:52
// 延迟1秒后每2秒执行一次
// 执行时间22019-06-13 11:41:54
// 延迟1秒后每2秒执行一次
// 执行时间22019-06-13 11:41:56
// 延迟1秒后每2秒执行一次
// 执行时间22019-06-13 11:41:58
// 延迟1秒后每2秒执行一次
public static void main2(String[] args){
ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
System.out.println("系统时间" + df.format(new Date()));
//延迟一秒执行
((ScheduledExecutorService) scheduledThreadPool).schedule(new Runnable() {
@Override
public void run() {
System.out.println("执行时间1" + df.format(new Date()));
System.out.println("延迟1秒执行");
}
},1,TimeUnit.SECONDS);
//延迟1秒执行后每2秒执行一次
((ScheduledExecutorService) scheduledThreadPool).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("执行时间2" + df.format(new Date()));
System.out.println("延迟1秒后每2秒执行一次");
}
},1, 2,TimeUnit.SECONDS);
}
//Executors.newSingleThreadExecutor():创建一个单线程化的线程池,
// 它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
//执行结果
// pool-1-thread-1正在执行第0个线程
// pool-1-thread-1正在执行第1个线程
// pool-1-thread-1正在执行第2个线程
// pool-1-thread-1正在执行第3个线程
// pool-1-thread-1正在执行第4个线程
public static void main3(String[] args){
ExecutorService singleThread = Executors.newSingleThreadExecutor();
for(int i=0;i<5;i++){
final int index = i;
singleThread.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "正在执行第" + index + "个线程");
}
});
}
}
}