多线程性能和基础

最简单开启多线程

//三个线程  业务写在 里面  分批次执行
new Thread(()->{
    testLock.buy();
}).start();

new Thread(()->{
    testLock.buy();
}).start();

new Thread(()->{
    testLock.buy();
}).start();

基础详解

多线程以及代理模式

package com.ruoyi.job.dmeo;

//静态代理总结
//真实对象和代理对象都要实现同一个接口
//代理对象要 代理真实角色
//都去实现 结婚的接口类 都是结婚的子类,  (方法定义传乐器,  现实传 唢呐、吉他、钢琴)
// 多线程也是代理模式, 实现接口 再去拓展

//好处;
//代理对象可以做很多真实对象做不了的事情   真交对象专注傲自已的事情

public class DaiLiDemo {
    public static void main(String[] args) {
        // Thread implements Runnable ,runnable只做run方法,Thread就是他的代理  
        new Thread(()-> System.out.println("多线程代理")).start();
        new WinddingCompany(new You()).happyMarry();

    }
}
//结婚的接口类
interface Marry{
    void happyMarry();
}
//真实角色 你
class You implements Marry{
    @Override
    public void happyMarry() {
        System.out.println("我要结婚了,敲开心!");
    }
}
// 代理角色 婚庆公司
class WinddingCompany implements Marry{
private Marry marry;

    public WinddingCompany(Marry marry) {
        this.marry = marry;
    }

    @Override
    public void happyMarry() {
            before();
            this.marry.happyMarry();
            after();
    }

    private void after() {
        System.out.println("结婚后收拾现场!");
    }

    private void before() {
        System.out.println("结婚前收彩礼!");
    }

}

线程优先级

优先级低只是意味着获得调度的概率低.并不是优先级低就不会被调用了.这都是看CPU的调度
使用多线程 先设置优先级, 1-10 , 10最优先 1最慢, 1-10以外的数字报错, 默认是5公平竞争
thread1.setPriority(10); //设置优先级

public class ThreadPriorityDemo  {
    public static void main(String[] args) {
        Thread thread1=new Thread(()-> System.out.println("-->"+Thread.currentThread().getPriority()));
        Thread thread2=new Thread(()-> System.out.println("-->"+Thread.currentThread().getPriority()));
        Thread thread3=new Thread(()-> System.out.println("-->"+Thread.currentThread().getPriority()));
        Thread thread4=new Thread(()-> System.out.println("-->"+Thread.currentThread().getPriority()));
        Thread thread5=new Thread(()-> System.out.println("-->"+Thread.currentThread().getPriority()));
        thread1.setPriority(1);
        thread2.setPriority(9);
        thread3.setPriority(7);
        thread4.setPriority(Thread.MAX_PRIORITY);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();
    }
}

线程停止

// 不建议使用官方stop  自己定义一个标识符 true 和false 去停止
public class ThreadStopDemo implements Runnable {
 //设置一个标识
    private boolean biaoshi;
    @Override
    public void run() {
        int i=0;
        System.out.println("县城"+i++);
    }

    public void stop(){
        this.biaoshi=false;
    }

    public static void main(String[] args) {
        ThreadStopDemo threadStopDemo=new ThreadStopDemo();
        new Thread(threadStopDemo).start();


        for (int i = 0; i < 10000; i++) {
            System.out.println("main"+i);
           if(i==9000){
                threadStopDemo.stop();
               System.out.println("县城该停止了");
           }
        }
    }
}

线程睡眠 sleep

睡眠不会释放锁
Thread.sleep(2000)//2000ms 2s

线程礼让 yield

礼让不一定成功,看cpu心情
Thread.yield();

线程插队 join

在这里插入图片描述

线程状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

守护线程

线程分为用户线程和守护线程,虚拟机必须确保用户线程执行完毕,虚拟机不用等待守护线程执行完毕, 例如,后台记录操作日志,监控内存,垃圾回收等待…

//设置守护线程
public class ThreadDaemonDemo {
    public static void main(String[] args) {
        Thread thread=new Thread(new God());
        thread.setDaemon(true);//设置为守护线程 直到所有线程执行完毕 ,还会执行一会儿然后结束
        thread.start();
        new Thread(new Yous()).start();
    }
}
//上帝
class God implements Runnable{
    @Override
    public void run() {
        while(true){
            System.out.println("上帝守护者你");
        }
    }
}
//你
class Yous implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("好好活好每一天");
        }
        System.out.println("=======God By=======");
    }
}

并发

线程不安全例子

//线程不安全 集合
public class ThreadNoSafe {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}
//3个人 抢票   出现同时抢到票的情况
public class ThreadBuyTicket {
    public static void main(String[] args) {
        BuyTicket buyTicket=new BuyTicket();
        Thread thread1=new Thread(buyTicket,"小明");
        Thread thread2=new Thread(buyTicket,"小红");
        Thread thread3=new Thread(buyTicket,"黄牛");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

class BuyTicket implements Runnable{

    private int ticket=10;
    private boolean flag=true;
    @Override
    public void run() {
            while(flag){
                buy();
            }
    }

    public void buy(){
        while(ticket<=0){
            flag=false;
            return;
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"拿到了"+ticket--);
    }
}

synchronized (同步)

实现就是 队列和锁: 10个人排队上厕所, 一个人进去锁门,出来后另一人进去锁门。
加锁影响性能,一般需要增删改的方法加锁, 查询不需要锁

  1. synchronized 方法 (锁的是this 当前类)
  2. synchronized 代码块 (可以锁 需要增删改的类)
锁 方法

方法上加 synchronized 其实锁的是this 当前类的增删改
如果 HeaderService 方法 调用了 Item类增删改 就只能锁块,锁方法失效

//3个人 抢票   出现同时抢到票的情况
public class ThreadBuyTicket {
    public static void main(String[] args) {
        BuyTicket buyTicket=new BuyTicket();
        Thread thread1=new Thread(buyTicket,"小明");
        Thread thread2=new Thread(buyTicket,"小红");
        Thread thread3=new Thread(buyTicket,"黄牛");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

class BuyTicket implements Runnable{

    private int ticket=10;
    private boolean flag=true;
    @Override
    public void run() {
            while(flag){
                buy();
            }
    }

    public synchronized void buy(){
        while(ticket<=0){
            flag=false;
            return;
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"拿到了"+ticket--);
    }
}
锁块

锁住header 类

 saveData(Header header){ 
 		//一些查询的业务操作 
		 if(true){
		 }
		 
	 synchronized (header){
	       //对Head表做修改增加的处理  
	 } 
	 //别的一些查询操作
}

死锁

案列

 public class DeadLockDemo {
    public static void main(String[] args) {
        Make make=new Make(0,"安琪");
        Make make2=new Make(1,"妲己");
        make.start();
        make2.start();
       /* new Thread(new Make(0,"安琪")).start();
        new Thread(new Make(0,"妲己")).start();*/
    }
    
}

//口红
class Lipstick  {

}
//镜子
class Mirror  {

}
//化妆
class Make extends Thread{
    //只有一个口红
    static Lipstick lipstick=new Lipstick();
    //只有一个镜子
    static Mirror mirror=new Mirror();

      int choice;//选择
      String girlName;//女孩名称

    public Make(int choice, String girlName) {
        this.choice = choice;
        this.girlName = girlName;
    }
    @Override
    public void run() {
        makeup();
            }
    //化妆
    private void  makeup(){
        if(choice==0){
            synchronized (lipstick){
                System.out.println(this.girlName+"获得口红的锁");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //睡眠一秒钟后去拿镜子
                synchronized (mirror){
                    System.out.println(this.girlName+"获得镜子的锁");
                }
            }
        }else{
            synchronized (mirror){
                System.out.println(this.girlName+"获得镜子的锁");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lipstick){
                    System.out.println(this.girlName+"获得口红的锁");
                }
            }
        }
    }
}
防止死锁
// 不要锁互相保持持有的锁
    //化妆
    private void  makeup(){
        if(choice==0){
            synchronized (lipstick){  //  多线程同时执行好多次类  难免会 同时走到 if  和else 里面  if里面不要持有口红的锁的时候 又去锁镜子,吧镜子锁放到外面 ,锁住口红的快包含了镜子,别人就 拿不到镜子了
                System.out.println(this.girlName+"获得口红的锁");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //睡眠一秒钟后去拿镜子
            synchronized (mirror){
                System.out.println(this.girlName+"获得镜子的锁");
            }
        }else{
            synchronized (mirror){
                System.out.println(this.girlName+"获得镜子的锁");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
               
            }
            synchronized (lipstick){
                System.out.println(this.girlName+"获得口红的锁");
            }
        }
    }

lock锁

核心代码
class TestLock{
    int tickNum=10;
    private final ReentrantLock lock=new ReentrantLock();
    public void buy(){
        lock.lock();
        try {
          //可以保证线程安全
        }finally {
            lock.unlock();
        }
    }
}

lock锁和synchronized 区别

在这里插入图片描述

案例
public class TestLockDemo {

    public static void main(String[] args) {
        TestLock testLock=new TestLock();
        //三个线程
        new Thread(()->{
            testLock.buy();
        }).start();

        new Thread(()->{
            testLock.buy();
        }).start();

        new Thread(()->{
            testLock.buy();
        }).start();
    }
}

class TestLock{
    int tickNum=10;
    private final ReentrantLock lock=new ReentrantLock();
    public void buy(){
        lock.lock();
        try {
            while (true){
                if(tickNum>0){
                    try {
                        Thread.sleep(1000);//睡眠就是为了等其他线程过来看看会不会同时抢
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"买到了第几个票:"+tickNum--);
                }else{
                    return;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

线程通信

基础讲解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标志位 案列 演员和观众

//演员表演完一个节目 观众观看完,演员继续表演,观众在观看
// this.wait() 等待表演, 观看完了 this.notifyAll(); //唤醒演员去表演 ,表演完,在唤醒观众去观看

public class TestPc {
    public static void main(String[] args) {
        Tv tv=new Tv();
        new Player(tv).start();
        new Watcher(tv).start();
    }
}
//生产者 --》演员
class Player extends  Thread{
    Tv tv;
    public Player(Tv tv){
        this.tv=tv;
    }
    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {
            if(i%2==0){
                this.tv.play("快乐大本营");
            }else{
                this.tv.play("B站生活");
            }
        }
    }
}
//消费者--》观众
class Watcher extends Thread{
    Tv tv;
    public Watcher(Tv tv){
        this.tv=tv;
    }
    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {
            this.tv.watch();
        }
    }
}
//TV
class Tv{
    //演员表演, 观众等待  true
    //观众观看    演员等待  false

    String voice;//节目
    boolean flag=true;  //标志位
    //表演
    public synchronized void play(String voice){
        if(!flag){
            try {
                this.wait(); //等待   不停止别的线程  
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演员表演了:"+voice);
        //通知观众观看
        this.notifyAll(); //唤醒
        this.voice=voice;
        this.flag=!this.flag;
    }
    //观看
    public synchronized void watch(){
        if(flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观众观看:"+this.voice);
        //通知演员表演
        this.notifyAll();
        this.flag=!this.flag;
    }
}

线程池

释义

在这里插入图片描述

案列
//线程池
public class TestPoolDemo {
    public static void main(String[] args) {
        ExecutorService service= Executors.newFixedThreadPool(10);
        service.execute(new Test1());
        service.execute(new Test1());
        service.execute(new Test1());
        service.execute(new Test1());
        service.execute(new Test1());
    }
}

class Test1 implements  Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

异步和多线程

源码解释

https://www.cnblogs.com/dennyzhangdd/p/9026303.html#_label1_0

区别

https://blog.csdn.net/woliuyunyicai/article/details/45165869
https://zhuanlan.zhihu.com/p/92035904

异步调用注意

https://blade.blog.csdn.net/article/details/44648667?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-3.control

多线程调用

    //多线程   批量增加 xml 500个一组
    private void threadExecuteData(List<Item> saveList){
        ExecutorService dataFileUploadExecutorService = ThreadConstants.getDataFileUploadExecutorService();
        //500个分组执行
        List<List<Item>> listSave = ListDeepCopy.splitTo(saveList, CompletePlanConstant.THREAD_NUM_DATA);
        final CountDownLatch endGate = new CountDownLatch(listSave.size());
        for (List<Item> deliveryCompleteMachineDetails : listSave) {
            final List<Item> listDataThread=deliveryCompleteMachineDetails;
            dataFileUploadExecutorService.execute(()->{
                try {
                    itemMapper.insertBatchList(listDataThread);
                }catch(Exception e){
                    throw new ServiceException("多线程增加异常,请联系管理员!");
                }finally{
                    endGate.countDown();
                }

            });
        }
        try {
            endGate.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //long entTime = System.currentTimeMillis();    //获取开始时间
        // System.out.println((saveList.size()+updateList.size())+"条数据,处理时间:" + (entTime - startTimeUpdate) + "ms");

    }

工具类

package org.springblade.delivery.plan.utils;

import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;


/**
 * Description
 * 配置参数常量类
 *
 * @author <a href="https://qiankunpingtai.cn">qiankunpingtai</a>
 * @Date: 2019/6/17 16:38
 */
public class ThreadConstants {
    /**
     * 默认的日期格式
     */
    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /**
     * 默认的分页起始页页码
     */
    public static final Integer DEFAULT_PAGINATION_PAGE_NUMBER = 1;
    /**
     * 无数据时列表返回的默认数据条数
     */
    public static final Long DEFAULT_LIST_NULL_NUMBER = 0L;
    /**
     * 默认的分页条数
     */
    public static final Integer DEFAULT_PAGINATION_PAGE_SIZE = 10;

    /**
     * 每页数据条数的参数名
     */
    public final static String PAGE_SIZE = "pageSize";
    /**
     * 每当前页码的参数名
     */
    public final static String CURRENT_PAGE = "currentPage";
    /**
     * 超级管理员的登录名
     */
    public final static String ADMIN_USER_NAME = "admin";
    /**
     * 十六进制默认前补位字符串
     */
    public final static String HEX_DEFAULT_INSERT_STRING = "0";
    /**
     * excle导入时,默认一次操作数据库的数据条数
     */
    public static final int IMPORT_ONCE_MAX_WRITE_SIZE = 50;
    /**
     * excle导入msisdn时,默认一次操作数据库的数据条数
     */
    public static final int IMPORT_MSISDN_ONCE_MAX_WRITE_SIZE = 10;
    /**
     * 一个公共的队列,用来存放短信写卡请求
     * */
    /**
     * 记录每一个线程的访问者
     */
    public volatile static Map<String, Object> CROSS_INTERCEPTOR_VISIT_MAP;
    public static final String CROSS_INTERCEPTOR_VISIT_MAP_STR = new String("cross_interceptor_visit");

    public static Map<String, Object> getCrossInterceptorVisitMap() {
        if (CROSS_INTERCEPTOR_VISIT_MAP == null) {
            synchronized (CROSS_INTERCEPTOR_VISIT_MAP_STR) {
                if (CROSS_INTERCEPTOR_VISIT_MAP == null) {
                    CROSS_INTERCEPTOR_VISIT_MAP = new ConcurrentHashMap<>();
                }
            }
        }
        return CROSS_INTERCEPTOR_VISIT_MAP;
    }

    /**
     * 一个公共线程池,用来处理卡数据上传的处理过程
     * 核心线程7个,最大线程数20,队列100,线程保有时间100S
     */
    public static ExecutorService DATA_FILE_UPLOAD_EXECUTOR_SERVICE = null;
    public static final String DATA_FILE_UPLOAD_EXECUTOR_SERVICE_STR = new String("data_file_upload");

    public static ExecutorService getDataFileUploadExecutorService() {
        if (DATA_FILE_UPLOAD_EXECUTOR_SERVICE == null) {
            synchronized (DATA_FILE_UPLOAD_EXECUTOR_SERVICE_STR) {
                if (DATA_FILE_UPLOAD_EXECUTOR_SERVICE == null) {
                    BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(10000);
                    DATA_FILE_UPLOAD_EXECUTOR_SERVICE = new ThreadPoolExecutor(10, 30, 300, TimeUnit.SECONDS, workQueue);
                }
            }
        }
        return DATA_FILE_UPLOAD_EXECUTOR_SERVICE;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值