Java核心知识点(持续更新中) Java核心知识点持续更新中线程与线程池线程线程池Java锁机制java线程模型java锁分类轻量级锁重量级锁ReentrantLock 底层原理与源码深度解析ReentrantReadWriteLock 深入理解读写锁CountDownLatchsemaphore 实现公平锁与非公平锁线程死锁与避免死锁Java 容器Collection、Map线程与线程池线程一、线程的状态二、 sleep、wait、join、yield 方法的区别1、sleep 与 wait 方法的区别1sleep 是 Thread 类的静态本地方法wait 则是 Object 类的本地方法。2sleep 方法不会释放 lock但是 wait 会释放而且会加入到等待队列中。3sleep 方法不依赖于同步器 synchronized但是 wait 方法需要依赖 synchronized关键字。4sleep 不需要被主动唤醒休眠时间结束后退出阻塞但是 wait 方法需要不指定时间时需要被别人中断。5sleep 方法一般用于当前线程休眠或者轮询暂停操作wait 方法则多用于线程之间的通信得益于wait会释放锁。6sleep 会让出 CPU 执行时间且强制上下文切换而 wait 则不一定wait 后可能还是有机会重新竞争到锁继续执行。2、yield 方法yield 方法执行后线程直接进入就绪态马上释放CPU的执行权但是依然保留了CPU的执行资格所以有可能CPU下次进行线程调度时还会让这个线程获取到执行权继续执行。3、join 方法线程执行 join 方法后会进入阻塞状态。例如在线程B中调用线程A的 join 方法那么线程B就会进入阻塞队列中直到线程A结束或者中断。三、线程的创建方式1、继承 Thread 类2、实现 Runnable 接口不带返回值3、实现 Callable 接口带返回值阻塞式获取返回值publicstaticvoidmain(String[]args){System.out.println(开始);//通过结合FutureTask类实现FutureTaskStringfutureTasknewFutureTask(()-{Stringresult;//结果处理过程......resultHello world!;returnresult;});ThreadthreadnewThread(futureTask);thread.start();try{//阻塞主线程并获取返回值StringresultfutureTask.get();System.out.println(result result);}catch(InterruptedException|ExecutionExceptione){e.printStackTrace();}System.out.println(结束);}4、通过线程池创建线。注意Java原生线程池阿里官方不推荐使用Executors原因如下线程池1、线程池的核心参数1corePoolSize核心线程数。2maxinumPoolSize最大线程数。3keepAliveTime空闲线程存活时间。4unit时间单位秒、分钟等。5workQueue任务队列存放任务的容器。6threadFactory线程工厂可以使用默认的或自定义的通常使用默认。7handler拒绝策略顾名思义拒绝线程访问JKD自带共有四种策略如下表拒绝策略名称描述new ThreadPoolExecutor.AbortPolicy()丢弃任务,并抛出RejectedExecutionException异常new ThreadPoolExecutor.DiscardPolicy()丢弃任务但是不抛出异常new ThreadPoolExecutor.DiscardOldestPolicy()丢弃队列最前面的任务然后重新提交被拒绝的任务new ThreadPoolExecutor.CallerRunsPolicy()该任务被线程池拒绝由调用 execute() 方法的线程执行该任务。如果执行程序已关闭则会丢弃该任务2、如何设置线程池参数publicstaticvoidmain(String[]args){//计算CPU核数intcpuCoresRuntime.getRuntime().availableProcessors();ThreadPoolExecutorthreadPoolnewThreadExecutor(corePoolSize,//核心线程数maxinumPoolSize,//最大线程数CPU密集型即高并发一般为CPU核数IO密集型一般为CPU核数*2keepAliveTime,//空闲线程的存活时间unit,//超时时间单位workQueue,//工作队列new LinkedBlockingDeque(3),阻塞队列threadFactory,//Executors.defaultThreadFactory(),默认创建线程的工厂一般不动handler//拒绝策略ThreadPoolExecutor.AbortPolicy(),队列满了还有任务直接抛出异常);}3、线程池的状态及说明4、线程池中的提交优先级和执行优先级参考文章https://blog.51cto.com/u_15891990/59080101提交优先级 核心线程 工作队列 非核心线程2执行优先级 核心线程 非核心线程 工作队列Java锁机制视屏地址B站讲的最好的Java锁机制java线程模型一、java线程模型参考文章https://www.cnblogs.com/songgj/p/15390160.htmljava锁分类参考文章方式一、彻底理解Java中的21种锁方式二、彻底理解Java中的21种锁轻量级锁一、CASCompare And Swap比较并交换。也被称为乐观锁、自旋锁。参考文章https://blog.csdn.net/weixin_43715214/article/details/128255225重量级锁一、synchronized 关键字非公平锁参考如下文章1、深入理解 synchronized一https://blog.csdn.net/weixin_43715214/article/details/1286081532、深入理解 synchronized二https://blog.csdn.net/weixin_43715214/article/details/1286285243、synchronized 锁升级过程4、HotSpot 虚拟机中 Java 对象的内存布局对象结构对象头5、分段式CASLongAdder。参考文章https://www.ngui.cc/el/1845495.html?actiononClickReentrantLock 底层原理与源码深度解析1、参考视屏B站讲的最好的Java锁机制【P8 - P13】2、参考文章深入ReentrantLock实现原理和源码分析一、ReentrantLock 公平锁与非公平锁1、ReentrantLock 公平锁与非公平锁参考文章https://zhuanlan.zhihu.com/p/453054632、ReentrantLock 中的 lock() 与 tryLock() 方法的区别publicclassTest{privatestaticReentrantLockreentrantLocknewReentrantLock();publicstaticvoidmain(String[]args){//阻塞式加锁业务代码不会执行reentrantLock.lock();//非阻塞式加锁可以根据尝试加锁是否成功来决定执行逻辑。通常结合while实现自旋booleantryLockResultreentrantLock.tryLock();/* 业务代码 ..... */}}ReentrantReadWriteLock 深入理解读写锁参考文章深入理解读写锁ReentrantReadWriteLock参考案例https://blog.csdn.net/wujian_csdn_csdn/article/details/114385796CountDownLatchCounDownLatch 表示计数器可以给 CountDownLatch 设置一个数字一个线程调用 CountDownLatch 的 await() 方法将会阻塞其他线程可以调用 CountDownLatch 的 countDown() 方法来对这个共享计数器中的数字减一当数字被减成 0 后所有的 await 的线程都将被唤醒。对应的底层原理就是调用 await() 方法的线程就会领用AQS排队一旦数字被减为 0 则会将 AQS 中排队的线程依次唤醒。建议参考源码semaphore 实现公平锁与非公平锁Semaphore 表示信号量可以设置许可的个数表示同时允许最多多少个线程使用改信号量通过 acquire() 来获取许可如果没有许可可用则线程阻塞并通过 AQS 来排队可以通过 release() 方法来释放许可当某个线程释放了许可后会从 AQS 中正在排队的第一个线程开始一次唤醒直到没有空闲许可。其中公平与非公平两种方式建议参考源码线程死锁与避免死锁一、如何查看线程死锁https://blog.csdn.net/fengsheng5210/article/details/123576559二、MySQL如何查看死锁https://blog.csdn.net/wufagang/article/details/125554792三、java如何避免死锁造成死锁的四个必要条件如下1、互斥一个资源每次只能被一个进程使用。2、请求且保持一个进程因请求资源而阻塞时对已获得的资源保持不放。3、资源不可剥夺进程已获得的资源在末使用完之前不能强行剥夺。4、循环等待若干进程之间形成一种头尾相接的循环等待资源关系。注意避免死锁只需要破坏其中一个条件就可以避免死锁而其中前 3 个条件是作为锁要符合的必要条件所以避免死锁就需要打破第 4 个条件循环等待。在开发过程中的注意事项1、注意加锁的顺序保证每个线程按同样的顺序进行加锁。2、加锁的时间可以针对锁设置超时时间。3、检查锁循环等待避免死锁。Java 容器Collection、MapJava容器知识点建议参考源码及网络资料深入理解。