源码+官方文档 面试高频问!
java.util 工具包、包、分类
业务:普通的线程代码 Thread
Runnable 没有返回值,效率相比于 Callable 相对较低!
public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }// 本地方法,底层的C++ , java 无法直接操作硬件 private native void start0();
package com.kuang; public class demo1 { public static void main(String[] args) { // 获取cpu的核数 // CPU 密集型, IO密集型 System.out.println(Runtime.getRuntime().availableProcessors()); } }
并发编程的本质:充分利用CPU的资源
所有的公司都很看重!
企业,挣钱 => 提高效率,裁员,找一个厉害的人顶替三个不怎么样的人;
人员(减),技术成本(高)
2.1、线程有几个状态public enum State { // 新生 NEW, // 运行 RUNNABLE, // 阻塞 BLOCKED, // 等待,死死地等 WAITING, // 超时等待,等不下去了就不等 TIMED_WAITING, // 终止 TERMINATED; }
wait/sleep 区别
来自不同的类 wait => Object sleep => Thread 企业当中,休眠,TimeUnit类 关于锁的释放 wait 会释放锁 sleep 睡觉了,抱着锁睡觉,不会释放锁! 使用的范围是不同的 wait 必须在同步代码块中 sleep 可以在任何地方睡 是否需要捕获异常(二者都需要捕获异常) wait 不需要捕获异常 sleep 必须要捕获异常公平锁:十分公平,可以先来后到
非公平锁:十分不公平,可以插队(默认)
package com.kuang; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SaleTicketDemo { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "A").start(); new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "B").start(); new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "C").start(); } } class Ticket { private int number = 30; Lock lock = new ReentrantLock(); public void sale() { lock.lock(); try { if (number > 0) { System.out.println(Thread.currentThread().getName() + "剩余" + (--number) + "张"); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } } 3.3、synchronized 和 Lock区别
面试的:单例模式、排序算法、生产者和消费者、死锁
4.1、生产者和消费者问题 synchronized 版package com.kuang.pc; public class A { public static void main(String[] args) { Data data = new Data(); new Thread(()->{ try { for (int i = 0; i < 10; i++) data.increament(); } catch (InterruptedException e) { e.printStackTrace(); } },"A").start(); new Thread(()->{ try { for (int i = 0; i < 10; i++) data.decreament(); } catch (InterruptedException e) { e.printStackTrace(); } },"B").start(); } } class Data{ private int number = 0; public synchronized void increament() throws InterruptedException { if (number!=0){ wait(); } number++; System.out.println(Thread.currentThread().getName()+"==>"+number); notifyAll(); } public synchronized void decreament() throws InterruptedException { if (number==0){ wait(); } number--; System.out.println(Thread.currentThread().getName()+"==>"+number); notifyAll(); } }
问题存在,A B C D 4个线程!虚假唤醒
if 改成 while
package com.kuang.pc; public class A { public static void main(String[] args) { Data data = new Data(); new Thread(()->{ try { for (int i = 0; i < 10; i++) data.increament(); } catch (InterruptedException e) { e.printStackTrace(); } },"A").start(); new Thread(()->{ try { for (int i = 0; i < 10; i++) data.decreament(); } catch (InterruptedException e) { e.printStackTrace(); } },"B").start(); new Thread(()->{ try { for (int i = 0; i < 10; i++) data.increament(); } catch (InterruptedException e) { e.printStackTrace(); } },"C").start(); new Thread(()->{ try { for (int i = 0; i < 10; i++) data.decreament(); } catch (InterruptedException e) { e.printStackTrace(); } },"D").start(); } } class Data{ private int number = 0; public synchronized void increament() throws InterruptedException { while (number!=0){ wait(); } number++; System.out.println(Thread.currentThread().getName()+"==>"+number); notifyAll(); } public synchronized void decreament() throws InterruptedException { while (number==0){ wait(); } number--; System.out.println(Thread.currentThread().getName()+"==>"+number); notifyAll(); } } 4.2、JUC版的生产者和消费者问题
代码实现:
package com.kuang.pc; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class A { public static void main(String[] args) { Data data = new Data(); new Thread(() -> { try { for (int i = 0; i < 10; i++) data.increament(); } catch (InterruptedException e) { e.printStackTrace(); } }, "A").start(); new Thread(() -> { try { for (int i = 0; i < 10; i++) data.decreament(); } catch (InterruptedException e) { e.printStackTrace(); } }, "B").start(); new Thread(() -> { try { for (int i = 0; i < 10; i++) data.increament(); } catch (InterruptedException e) { e.printStackTrace(); } }, "C").start(); new Thread(() -> { try { for (int i = 0; i < 10; i++) data.decreament(); } catch (InterruptedException e) { e.printStackTrace(); } }, "D").start(); } } class Data { private int number = 0; Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); public void increament() throws InterruptedException { lock.lock(); try { while (number != 0) { condition.await(); } number++; System.out.println(Thread.currentThread().getName() + "==>" + number); condition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void decreament() throws InterruptedException { lock.lock(); try { while (number == 0) { condition.await(); } number--; System.out.println(Thread.currentThread().getName() + "==>" + number); condition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
任何一个新的技术,绝对不仅仅是覆盖了原来的技术,一定会有优势和补充!
4.3、Condition-----精准的通知和唤醒线程代码测试:
package com.kuang.pc; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class A { public static void main(String[] args) { Data data = new Data(); new Thread(() -> { for (int i = 0; i < 10; i++) data.printA(); }, "A").start(); new Thread(() -> { for (int i = 0; i < 10; i++) data.printB(); }, "B").start(); new Thread(() -> { for (int i = 0; i < 10; i++) data.printC(); }, "C").start(); } } class Data { private int number = 1; private Lock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); public void printA() { lock.lock(); try { while (number!=0){ condition1.await(); } number++; System.out.println(Thread.currentThread().getName()+"=>AAAAAA"); condition2.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printB() { lock.lock(); try { while (number!=1){ condition2.await(); } number++; System.out.println(Thread.currentThread().getName()+"=>BBBBBB"); condition3.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printC() { lock.lock(); try { while (number!=2){ condition3.await(); } number=0; System.out.println(Thread.currentThread().getName()+"=>CCCCCC"); condition1.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
如何判断锁的对象!永远知道什么是锁,锁到底锁的是谁?
对象、Class
hashSet 底层是什么?
6.3、Map不安全回顾Map的基本操作
Callable 和 Runnable 的区别:
可以有返回值 可以抛出异常 方法不同,call()/ run()代码测试:
package com.kuang; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class Test { public static void main(String[] args) throws ExecutionException, InterruptedException { // 适配类 FutureTask futureTask = new FutureTask(new Callable() { @Override public Integer call() throws Exception { System.out.println("call()"); return 1024; } }); new Thread(futureTask,"A").start(); new Thread(futureTask,"B").start(); // 结果会被缓存,效率高 // 获取Callable返回结果并打印 System.out.println(futureTask.get()); } }
细节:
有缓存 结果可能需要等待,会阻塞!package com.kuang; import java.util.concurrent.CountDownLatch; // 计数器 public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { //总数是6,必须要执行任务的时候,再使用! CountDownLatch countDownLatch = new CountDownLatch(6); for (int i = 1; i <= 6; i++) { new Thread(() -> { System.out.println(Thread.currentThread().getName()+"Go Out"); countDownLatch.countDown();// 数量减一 }, String.valueOf(i)).start(); } countDownLatch.await();// 等待计数器归零,再向下执行 System.out.println("Close Door"); } }
加法计数器
package com.kuang; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierDemo { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> { System.out.println("召唤神龙!"); }); for (int i = 1; i <= 7; i++) { final int temp = i; new Thread(() -> { System.out.println(Thread.currentThread().getName()+"收集了"+temp+"颗龙珠"); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); } } } 8.3、Semaphore
Semaphore:信号量
package com.kuang; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class SemaphoreDemo { public static void main(String[] args) { //线程数量:停车位!限流! Semaphore semaphore = new Semaphore(3); for (int i = 1; i <= 6; i++) { new Thread(() -> { //acquire();得到 try { semaphore.acquire(); System.out.println(Thread.currentThread().getName()+"抢到车位"); TimeUnit.SECONDS.sleep(2); System.out.println(Thread.currentThread().getName()+"离开车位"); } catch (InterruptedException e) { e.printStackTrace(); }finally { semaphore.release(); } //release() 释放 }, String.valueOf(i)).start(); } } }
ReadWriteLock
package com.kuang; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 独占锁(写锁) 一次只能被一个线程占有 * 共享锁(读锁) 多个线程可以同时占有 */ public class ReadWriteLockDemo { public static void main(String[] args) { MyCache myCache = new MyCache(); for (int i = 1; i <= 10; i++) { final int temp = i; new Thread(() -> { myCache.put(temp+"",temp+""); }, String.valueOf(i)).start(); } for (int i = 1; i <= 10; i++) { final int temp = i; new Thread(() -> { myCache.get(temp+""); }, String.valueOf(i)).start(); } } } class MyCache{ private volatile Map<String,String> map = new HashMap<>(); private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public void put(String key,String value){ readWriteLock.writeLock().lock(); try { System.out.println(Thread.currentThread().getName()+"写入"); map.put(key,value); System.out.println(Thread.currentThread().getName()+"写入成功"); } catch (Exception e) { e.printStackTrace(); } finally { readWriteLock.writeLock().unlock(); } } public void get(String key){ readWriteLock.readLock().lock(); try { System.out.println(Thread.currentThread().getName()+"读取"); map.get(key); System.out.println(Thread.currentThread().getName()+"读取成功"); } catch (Exception e) { e.printStackTrace(); } finally { readWriteLock.readLock().unlock(); } } }
阻塞队列:
BlockingQueue BlockingQueue 不是新的东西
SynchronousQueue 同步队列代码略
线程池:三大方法、7大参数、4种拒绝策略
线程池:三大方法package com.kuang; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Demo { public static void main(String[] args) { // Executors.newSingleThreadExecutor(); ExecutorService threadPool = Executors.newCachedThreadPool(); // Executors.newFixedThreadPool(3); try { for (int i = 0; i < 10; i++) { threadPool.execute(() -> { System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { threadPool.shutdown(); } } } 7大参数
源码探究
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); } public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//21亿 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } //本质ThreadPoolExecutor() public ThreadPoolExecutor(int corePoolSize,//核心线程池大小 int maximumPoolSize,//最大核心线程池大小 long keepAliveTime,//超时了没有人调用就会释放 TimeUnit unit,//超时单位 BlockingQueue<Runnable> workQueue,//阻塞队列 ThreadFactory threadFactory,//线程工厂,创建线程的,一般不用动 RejectedExecutionHandler handler//拒绝策略) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; } 手动创建一个线程池
package com.kuang; import java.util.concurrent.*; public class Demo { public static void main(String[] args) { ThreadPoolExecutor threadPool = new ThreadPoolExecutor( 2, 5, 3, TimeUnit.SECONDS, new LinkedBlockingDeque<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() ); try { for (int i = 0; i < 10; i++) { threadPool.execute(() -> { System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { threadPool.shutdown(); } } } 四种拒绝策略 小结和拓展
了解:IO密集型,CPU密集型(调优)
package com.kuang; import java.util.concurrent.*; public class Demo { public static void main(String[] args) { //CPU密集型 ThreadPoolExecutor threadPool = new ThreadPoolExecutor( 2, Runtime.getRuntime().availableProcessors(), 3, TimeUnit.SECONDS, new LinkedBlockingDeque<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() ); try { for (int i = 0; i < 10; i++) { threadPool.execute(() -> { System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { threadPool.shutdown(); } } }
新时代的程序员:lambda表达式、链式编程、函数式接口、Stream流式计算
函数式接口 有且只有一个方法的接口@FunctionalInterface public interface Runnable { public abstract void run(); } //超级多FunctionalInterface //简化编程模型,在新版本的框架底层大量应用! //foreach(消费者类的函数式接口)
代码测试:
Function函数式接口
断定型接口有一个输入参数,返回值只能式 布尔值! Consumer消费型接口 Supplier供给型接口大数据:存储 + 计算
存储:集合、MySQL 本质就是存储东西的
计算都应该交给流来操作!
ForkJoin 在JDK1.7,并行执行任务!提高效率。大数据量!
大数据:Map Reduce(把大任务拆分为小任务)
ForkJoin 特点:工作窃取这里面维护的都是双端队列
测试:
线程工作内存主内存
8种操作:
问题:程序不知道主内存的值已经被修改过了
原子性:不可分割
线程A在执行任务的时候,不能被打扰的,也不能被分割。要么同时成功,要么同时失败
如果不加 lock 和 synchronized ,怎么样保证原子性
使用原子类,解决 原子性问题
这些类的底层都直接和操作系统挂钩!在内存中修改值!Unsafe类是一个很特殊的存在!
指令重排什么是指令重排:你写的程序,计算机并不是按照你写的那样去执行的。
源代码-->编译器优化的重排-->指令并行也可能重排-->内存系统也会重排-->执行
饿汉式 DCL懒汉式,探究!
饿汉式 DCL 懒汉式 静态内部类 单例不安全,反射 枚举枚举类型的最终反编译源码:
大厂你必须要深入研究底层!有所突破!修内功,操作系统,计算机网络原理
Unsafe 类CAS:比较当前工作内存中的值和主内存中的值,如果这个值是期望的,那么则执行操作!如果不是就一直循环!
缺点:
循环会耗时 一次性只能保证一个共享变量的原子性 存在ABA问题 CAS之ABA问题(狸猫换太子)带版本号的原子操作!
注意:
非公平锁:非常不公平,可以插队(默认都是非公平)
可重入锁可重入锁(递归锁)
synchronized版(代码略)
lock版(代码略)
自旋锁spinlock
自定义的锁
测试:
死锁死锁是什么?
死锁测试,怎么排除死锁:
解决问题:
面试,工作中!排查问题:
日志9人(领导不喜欢,运维不喜欢) 堆栈 1人(领导喜欢,此方法不用麻烦运维)相关知识
Mind+Python编程进阶系列课程—06植物监测仪 DF创客社区
菜根花小宝贝
【免费】我自己写的网络聊天系统资源
软件大赛
【青少年编程】【二级】绘制五彩缤纷的多瓣花
已完结的惊悚小说
【已结课】商业插画实战进阶班
编程绘画插花图片技巧与实例分享
Python中的线程池和进程池的详解
深度学习应用开发
网址: 多线程进阶 => JUC并发编程(已完结,但图片未提交) https://m.huajiangbk.com/newsview854172.html
上一篇: 圣诞节礼盒款照片书34p |
下一篇: 【尺素纸艺】新中式文化礼品盒 |