JAVA多线程+线程池学习

JAVA多线程学习

Java 多线程编程

多线程理论相关可直接上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 + "个线程");
                }
            });
        }
    }


}

你可能感兴趣的:(java,学习)