Java Springboot 线程池使用

Java Springboot 线程池使用

一、基本概念

1.进程:一个程序的执行,包含多个线程
2.线程:一个程序执行中的片段但,进程执行中的最小单位
3.使用场景:
        ①后台任务:定时发送大量邮件
        ②异步处理:统计、日志
        ③分布式计算、分片下载、断点续传
4.用户线程和守护线程
用户线程:程序本身执行的线程
守护线程:为程序提供通用服务的线程(GC 垃圾回收线程)
用户线程存在,JVM不会离开;用户线程执行完成退出,无论守护线程是否存在,JVM都将离开
5.同一CPU内核,同一时间,只能执行一个线程
   线程调度器,分配时间片
   线程优先级分为10级,1最低,10最高
6.线程的停止:采用中断
7.线程的状态:
        ①NEW
        ②RUNNABLE
        ③BLOCKED
        ④WAITING
        ⑤TIMED_WAITING
        ⑥TERMINATED
在这里插入图片描述
8.控制线程执行顺序:join方法(优先级是提高概率,并不绝对)
9.线程安全:子线程访问共享变量,共享变量在主内存中,访问时会将共享变量拷贝至自己的工作内存,操作完成后再写回主变量
10.Java并发编程三大特性:原子性、可见性、有序性

二、线程演示
1.线程创建

package com.atguigu.thread;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Description: 多线程Demo
 *
 * @Author: 
 * @Date: 2021-04-25 20:53
 * @version: V1.0.0
 */
@Slf4j
public class ThreadDemo {

    private static int num=10;

    public static void main(String[] args) {

        /**
         * 采用继承的方式,只能单继承Thread
         * 采用实现接口的方式,可以在实现接口的基础上再进行一次继承
         * 同时,采用接口的写法可以改为匿名内部类的方式,进一步简化为Lambda表达式形式
         */

        TestThread testThread = new TestThread();
        testThread.start();

        Thread thread = new Thread(new TestRunnable());
        thread.start();

        Thread threadN = new Thread(new Runnable(){
            @Override
            public void run(){
                log.info("匿名内部类形式");
            }
        });
        threadN.start();

        Thread threadL = new Thread(()->{
            log.info("Lambda表达式形式");
        });
        threadL.start();

        /**
         * 带返回值的线程
         */
        FutureTask<Integer> futureTask = new FutureTask<>(new TestCallable());
        Thread threadRet = new Thread(futureTask);
        threadRet.start();
        try {
            //得到线程执行处理结果
            Integer result = futureTask.get();
            log.info("得到线程执行处理结果:{}",result);
        }catch (ExecutionException exception) {
            log.error("",exception);
        }catch (InterruptedException exception) {
            log.error("",exception);
        }

    }

    /**
     * 继承Thead类,实现Run方法
     */
    static class TestThread extends Thread{
        @Override
        public void run(){
            for (int i=0;i<num;i++){
                log.info("Print 【{}】 Times",i);
            }
        }
    }

    /**
     * 实现Runnable接口,实现Run方法
     */
    static class TestRunnable implements Runnable{

        @Override
        public void run() {
            for (int i=0;i<num;i++){
                log.info("Print 【{}】 Times",i);
            }
        }
    }

    /**
     * 实现Callable接口,实现带返回值的任务
     */
    static class TestCallable implements Callable<Integer>{

        @Override
        public Integer call() throws Exception {
            int sum=0;
            for (int i=0;i<num;i++){
                log.info("Print 【{}】 Times",i);
                sum+=i;
            }
            return sum;
        }
    }

}

2.线程停止

package com.atguigu.thread;

import lombok.extern.slf4j.Slf4j;

/**
 * Description: 线程停止的方法
 *
 * @Author: 
 * @Date: 2021-04-25 21:47
 * @version: V1.0.0
 */
@Slf4j
public class ThreadStopDemo {


    /**
     * 优雅的终止线程
     * threadTest.interrupt() 中断线程
     * Thread.currentThread().isInterrupted() 线程是否中断
     * @param args
     */
    public static void main(String[] args) {

        Thread threadTest = new Thread(()->{
            while (true){
                if(Thread.currentThread().isInterrupted()){
                    break;
                }
                log.info("线程执行中......");
            }
        });
        threadTest.start();
        /**
         * 主线程休眠2秒
         * 然后将子线程中断
         */
        try {
            Thread.sleep(2000);
            threadTest.interrupt();
        } catch (InterruptedException interruptedException) {
            interruptedException.printStackTrace();
        }
    }
}

3.用户线程和守护线程

package com.atguigu.thread;

import lombok.extern.slf4j.Slf4j;

/**
 * Description: 用户线程和守护线程测试
 *
 * @Author: 
 * @Date: 2021-04-25 21:27
 * @version: V1.0.0
 */
@Slf4j
public class ThreadDaemonDemo {

    private static int num = 100;

    /**
     * new Thread 默认为非守护进程
     * 设置为守护进程后,当threadUser执行完成时,threadDaemon立即结束
     * @param args
     */
    public static void main(String[] args) {

        /**
         * 守护线程
         */

        Thread threadDaemon = new Thread(()->{
            for (int i=0;i<num;i++){
                try {
                    Thread.sleep(200);
                    log.info("守护线程:【{}】",i);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
            }
        });
        threadDaemon.setDaemon(false);
        threadDaemon.start();

        /**
         * 用户线程
         */

        Thread threadUser = new Thread(()->{
            for (int i=0;i<num;i++){
                try {
                    Thread.sleep(50);
                    log.info("用户线程:【{}】",i);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
            }
        });
        threadUser.start();
    }
}

4.线程优先级

package com.atguigu.thread;

import lombok.extern.slf4j.Slf4j;

/**
 * Description: 线程优先级测试
 *
 * @Author: 
 * @Date: 2021-04-25 21:36
 * @version: V1.0.0
 */
@Slf4j
public class ThreadPriority {

    private static int num = 100;

    /**
     * 设置优先级1-10 默认为5
     * @param args
     */
    public static void main(String[] args) {

        /**
         * 守护线程
         */

        Thread threadFirst = new Thread(()->{
            for (int i=0;i<num;i++){
                log.info("线程1:【{}】",i);
            }
        });
        threadFirst.setPriority(1);
        threadFirst.start();

        /**
         * 用户线程
         */

        Thread threadSecond = new Thread(()->{
            for (int i=0;i<num;i++){
                log.info("线程2:【{}】",i);
            }
        });
        threadSecond.setPriority(10);
        threadSecond.start();
    }
}

5.线程顺序执行

package com.atguigu.thread;

import lombok.extern.slf4j.Slf4j;

/**
 * Description: 线程执行顺序
 *
 * @Author: 
 * @Date: 2021-04-25 22:22
 * @version: V1.0.0
 */
@Slf4j
public class ThreadJoin {

    private static int num = 100;

    /***
     * 控制线程T1、T2、T3按顺序执行
     * join A { B.join() } 则A会在B执行完后执行
     * @param args
     */
    public static void main(String[] args) {

        Thread t1 = new Thread(()->{
            for (int i=0;i<num;i++){
                log.info("线程0:【{}】",i);
            }
        });

        Thread t2 = new Thread(()->{
            try {
                t1.join();
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
            for (int i=0;i<num;i++){
                log.info("线程1:【{}】",i);
            }
        });

        Thread t3 = new Thread(()->{
            try {
                t2.join();
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
            for (int i=0;i<num;i++){
                log.info("线程2:【{}】",i);
            }
        });
        t1.start();
        t2.start();
        t3.start();
    }
}

6.线程安全与锁(不加锁则会出现卖票混乱)

package com.atguigu.thread;

import lombok.extern.slf4j.Slf4j;

/**
 * Description: 线程安全测试
 *
 * @Author: 
 * @Date: 2021-04-25 22:53
 * @version: V1.0.0
 */
@Slf4j
public class ThreadSafeDemo {

    private static int tickets=100;

    public static void main(String[] args) {
        Object o = new Object();
        Runnable runnable = ()->{
            while (true){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
                synchronized (o){
                    if(tickets>0){
                        tickets--;
                        log.info("{} 卖了一张票,剩余 {}",Thread.currentThread().getName(),tickets);
                    }else{
                        break;
                    }
                }
            }
        };

        Thread t1 = new Thread(runnable,"窗口1");
        Thread t2 = new Thread(runnable,"窗口2");
        Thread t3 = new Thread(runnable,"窗口3");
        t1.start();
        t2.start();
        t3.start();

    }
}

7.线程通信演示 等待wait和唤醒notify

package com.atguigu.thread;

import lombok.extern.slf4j.Slf4j;

/**
 * Description: 线程通信演示 等待:wait 唤醒:notify
 *
 * @Author: 
 * @Date: 2021-04-28 23:34
 * @version: V1.0.0
 */
@Slf4j
public class ThreadCommunication {

    public static void main(String[] args) {

        NumMode  numMode = new NumMode();

        /**
         * 奇数情况输出
         */
        new Thread(()->{
            while (true){
                synchronized (numMode){
                    if(numMode.num<100){
                        if(numMode.num%2!=0){
                            log.info("奇数打印:{}",numMode.num);
                            numMode.num++;
                            numMode.notify();
                        }else{
                            try {
                                numMode.wait();
                            } catch (InterruptedException interruptedException) {
                                interruptedException.printStackTrace();
                            }
                        }
                    }else {
                        break;
                    }
                }
            }
        }).start();

        /**
         * 偶数情况输出
         */
        new Thread(()->{
            while (true){
                synchronized (numMode){
                    if(numMode.num<100){
                        if(numMode.num%2==0){
                            log.info("偶数打印:{}",numMode.num);
                            numMode.num++;
                            numMode.notify();
                        }else{
                            try {
                                numMode.wait();
                            } catch (InterruptedException interruptedException) {
                                interruptedException.printStackTrace();
                            }
                        }
                    }else {
                        break;
                    }
                }
            }
        }).start();
    }

    static class NumMode{
        int num=0;
    }
}

8.消费和生产者模型演示 等待wait和唤醒notify

package com.atguigu.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;

/**
 * Description: 生产者消费者模型
 *
 * 生产者:做手机
 * 消费者:买手机
 * 手机店:库存容量30台
 *
 * @Author: 
 * @Date: 2021-04-28 23:57
 * @version: V1.0.0
 */
@Slf4j
public class ProductionAndConsumption {

    static int version = 1;

    /**
     * 顾客
     */
    static class CustomerTask implements Runnable{
        MobileShop mobileShop;
        public CustomerTask(MobileShop mobileShop) {
            this.mobileShop = mobileShop;
        }

        @Override
        public void run() {
            while (true){
                synchronized (mobileShop){
                    if(mobileShop.phoneList.size()>0){
                        mobileShop.phoneList.poll();
                        mobileShop.notifyAll();
                        log.info(":{}购买了一台手机",Thread.currentThread().getName());
                    }else{
                        //手机抢光了
                        try {
                            mobileShop.wait();
                        } catch (InterruptedException interruptedException) {
                            interruptedException.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * 山寨手机厂
     */
    static class ProductTask implements Runnable{

        MobileShop mobileShop;
        public ProductTask(MobileShop mobileShop) {
            this.mobileShop = mobileShop;
        }

        @Override
        public void run() {
            while (true){
                synchronized (mobileShop){
                    if(mobileShop.phoneList.size()<30){
                        Phone phone = new Phone();
                        phone.setModel("小米"+version);
                        version++;
                        mobileShop.phoneList.push(phone);
                        mobileShop.notifyAll();
                        log.info("{}:生产了一台手机,共{}版本了",Thread.currentThread().getName(),version);
                    }else{
                        //库存已满,停止生产
                        try {
                            mobileShop.wait();
                        } catch (InterruptedException interruptedException) {
                            interruptedException.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * 手机店
     */
    static class MobileShop{
        LinkedList phoneList = new LinkedList();
    }

    /**
     * 手机
     */
    static class Phone{
        String model;
        public void setModel(String model) {
            this.model = model;
        }
        public String getModel() {
            return model;
        }

    }

    public static void main(String[] args) {
        MobileShop mobileShop = new MobileShop();
        new Thread(new ProductTask(mobileShop)).start();
        new Thread(new CustomerTask(mobileShop)).start();
        new Thread(new CustomerTask(mobileShop)).start();


    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猪悟道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值