栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java线程池

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java线程池

1.线程池的基本使用
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyPool {
    public static void main(String[] args) {
        //这是一个线程创建工具,他会判断线程池子里面是否有空闲的线程,有就用空闲的线程
        //没有则创建,这边能创建最大的线程就是Int的最大值,这个线程池某种意义上线程数量
        //无限制,这边注意一下 ExecutorService这个是一个接口
        ExecutorService executorService = Executors.newCachedThreadPool();
        Executors.newFixedThreadPool(10);//这种创建方式是创建一个线程上限的池子
        //这边的入参是Runabled接口,所以可以lamda
        executorService.submit(()->{
            System.out.println(Thread.currentThread().getName()+"吃饭");
        });

        executorService.submit(()->{
            System.out.println(Thread.currentThread().getName()+"吃饭");
        });
        executorService.submit(()->{
            System.out.println(Thread.currentThread().getName()+"吃饭");
        });
        //关闭线程池
        executorService.shutdown();
    }
}
2.线程池的创建
import java.util.concurrent.*;

public class MyPoolThread {
    public static void main(String[] args) {
        int corePoolSize = 5;//核心线程数量,创建就不会被销毁
        int maximumPoolSize =10;//全部的数量
        long keepAliveTime=10;//非核心线程多场失效
        TimeUnit unit = TimeUnit.SECONDS;//单位
        //这边的队列是如果我所有的线程都有事,那么再来一个新的任务就到队列等待线程释放
        BlockingQueue workQueue = new ArrayBlockingQueue<>(1);
        //如果队列也满了,那么就开始拒绝。
        //拒绝策略一共有四种
        //ThreadPoolExecutor.AbortPolicy 拒绝并跑出异常
        //ThreadPoolExecutor.DiscardPolicy 拒绝不抛出异常
        //ThreadPoolExecutor.CallerRunsPolicy  抛弃队列里面等待时间最长的任务
        //ThreadPoolExecutor.DiscardOldestPolicy 不用线程池,直接给其他线程处理
        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
        ThreadPoolExecutor threadPoolExecutor =
                new ThreadPoolExecutor(corePoolSize,
                        maximumPoolSize,
                        keepAliveTime,
                        unit,
                        workQueue,
                        Executors.defaultThreadFactory(),
                        handler);
        threadPoolExecutor.execute(()->{
            System.out.println("运行任务");
        });
    }
}
3.volatile关键字的用法
public class MyPoolVolatile {
    //有10个汉堡
    private static volatile int HanBaoBao = 10;
    //下面要做一个事情,就是我有两个线程一个叫老7要去偷吃老八的汉堡,
    // 但是老八每天都会数一下,发现了就会报警!
    //这边的代码会陷入死循环
    //有两个解决方法
    //第一种就是    private static volatile int HanBaoBao = 10;
    //第二种就是加把锁
    //这边的机制其中一个线程如果改了共同的变量,
    // 那么就提醒使用这个变量的线程,重新拿一下值
    public static void main(String[] args) {
        //这是老八
        new Thread(()->{
        while(true){
            if(HanBaoBao!=10){
                System.out.println("嗨嗨害!报警!");
                break;
            }else{

            }
        }
        }).start();
        //这边是小偷我偷汉堡
        new Thread(()->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            HanBaoBao = 7;
        }).start();
    }
}
4.多线程操作共享数据(多线程重点)

这边呢也是我在工作中的时候呢遇到一个比较重要的问题,我多线程去操作某一集合对象,如果仅仅是查询其实也无所谓,但是设计到更改,那么这个共享数据也能就会产生问题,那么有问题就需要解决!

4.1数据原子性--举个反例

这边用volatile 关键字也是不行的,同步代码块是可以,但是效率较慢

public class ThreadAddNum {
    //我现在有个场景,如果我有一百个线程去操作num,每个线程我加100次
    //那么最后的结果是不是num就是10000?这边的结果就不是?如果是10000你多试几次
    //会发现结果是飘忽不定的
    //这就出现了问题
    private static int num = 0;
    public static void main(String[] args) {
        for(int i=0;i<100;i++){
             new Thread(()->{
                 for(int a=0;a<100;a++){
                     num++;
                     System.out.println(num);
                 }
             }).start();
        }
    }

}
4.2 解决方案 自旋锁+CAS算法
import java.util.concurrent.atomic.AtomicInteger;

public class MyAomic {

//    private static int num = 0;
    private static AtomicInteger num = new AtomicInteger(0);
    public static void main(String[] args) {
        //这边有很多类Atomic包里面的类我这边只用到了
        //integer所以就举一下这个例子
        AtomicInteger atomicInteger =  new AtomicInteger(10);
        //下面都是一些操作这个对像的方法,和多线程并没有关系
        System.out.println(atomicInteger.get());//获取这个对象里面的值
        System.out.println(atomicInteger.getAndIncrement());//自增之前的值
        System.out.println(atomicInteger.incrementAndGet());//自增之后的值,看名字都是有说法的规律自己找
        System.out.println(atomicInteger.getAndAdd(88));
        System.out.println(atomicInteger.getAndSet(0));
        for(int i=0;i<100;i++){
            new Thread(()->{
                for(int a=0;a<100;a++){
                    num.incrementAndGet();
                    System.out.println(num.get());
                }
            }).start();
        }

    }
}
4.3 乐观锁和悲观锁

悲观锁就是synchronized代码块 ,我默认就认为别人会抢我的老婆。我每次干活我就先锁门,防止别人抢我老婆。

乐观锁就是我默认不会抢我老婆,但是我每天回家时候我检查一下,看看是不是原来的形状。

4.4 HashMap线程不安全

HashMap不安全,可以替换成HashTable ,但是效率很低,那么为了效率就会有专门解决这个问题的类对象

import java.util.HashMap;

public class MyHash {
    private static HashMap map =new HashMap<>();

    public static void main(String[] args) throws InterruptedException {
        new  Thread(()->{
            for (int i = 0; i < 50; i++) {
                map.put(i+"",i+"");
            }
        }).start();

        new  Thread(()->{
            for (int i = 50; i < 100; i++) {
                map.put(i+"",i+"");
            }
        }).start();

        new  Thread(()->{
            for (int i = 100; i < 150; i++) {
                map.put(i+"",i+"");
            }
        }).start();
        Thread.sleep(1000);
        for (int i = 0;i<200;i++)
            System.out.println(map.get(i+""));
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/756615.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号