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+""));
}
}



