哼哼啊啊啊啊啊啊啊啊啊又是不妙的一天
//锁对象Lock
Lock Lock = new ReentrantLock( fair: true);//创建锁对象
默认都是非公平锁
死锁
死锁是指两个或多个线程在执行过程中,因争夺资源而造成的一种互相等待的阻塞现象,导致线程都无法向前推进。
死锁的发生需要满足以下四个必要条件,这些条件被称为死锁的“四驾马车”:
1. 互斥条件:资源只能被一个线程占用,其他线程不能同时使用该资源。例如,打印机就是典型的互斥资源,同一时间只能由一个进程使用。
2. 占有和等待条件:一个线程至少占有一个资源,同时等待获取其他被其他线程占有的资源。这种一边占有资源,一边等待其他资源的情况是死锁的关键。
3. 不可剥夺条件:已经分配给线程的资源在使用完成之前不能被其他线程剥夺,只能由占有资源的线程主动释放。
4. 循环等待条件:存在一个线程资源的循环等待链,每个线程占有下一个线程所需的资源,从而形成一个闭环的互相等待的状态。
例,线程A锁定了资源1,然后尝试锁定资源2;同时线程B锁定了资源2,接着尝试锁定资源1,这样线程A和线程B都在等待对方释放资源,造成了死锁。
综上所述,死锁是多线程编程中一个复杂且常见的问题,处理不当会导致程序完全停止响应。理解死锁产生的条件和掌握相应的解决方案对于编写高效、安全的多线程应用至关重要。
唤醒操作:必须在同步代码块中进行
可以先跑一部分,然后去放入等待池,等下一个来把他唤醒替换他的位置
这样会导致最后卡一条线程在等待池
因此需要在最后再设置一条唤醒来解救最后一条卡住的线程
重新运行直接在catch的位置,不会跑上面跑过的
//wait和sleep的区别是什么
wait是Object里面的方法,可以有锁对象调用,让执行到该代码的线程进入到等待状态
sleep是Thread类中定义的静态方法,也可以让执行到该行的线程进入等待状态
区别:sleep需要传入一个毫秒数,到达时间后会自动唤醒
wait不能自动唤醒,必须调用notify或者notifyAll方法唤醒
sleep设置时间到了自己就醒来了
wait方法会解除锁状态,其他线程可以进入运行
sleep方法会保持锁状态进入等待状态
说明线程池的七个参数
corePoolSize:
核心线程数。线程池中始终保持存活的线程数量,即使它们处于空闲状态也不会被回收,除非设置了allowCoreThreadTimeOut。
maximumPoolSize:
最大线程数。线程池中允许的最大线程数量,包括核心线程数和非核心线程数。当工作队列满了且有新的任务提交时,线程池可以创建新的线程,直到达到最大线程数。
keepAliveTime:
线程空闲时间。非核心线程在空闲超过该时间后会被回收,直到线程池的线程数不超过核心线程数为止。
unit:
空闲时间的单位。通常是 TimeUnit.SECONDS 或 TimeUnit.MILLISECONDS 等
workQueue:
工作队列。用于保存等待执行的任务的阻塞队列。常见的类型有 LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue 等。
threadFactory:
线程工厂。用于创建新线程,默认使用 Executors.defaultThreadFactory(),可以通过自定义线程工厂来修改线程的名称、优先级等。
handler:
拒绝策略。当工作队列和线程池都满了,无法继续接受新任务时,用于处理新提交的任务的策略。常见的有 AbortPolicy(抛出异常)、CallerRunsPolicy(由提交任务的线程执行)、DiscardPolicy(丢弃任务)、DiscardOldestPolicy(丢弃队列头部的任务)。
2.四种回绝策略
AbortPolicy (默认)放弃该任务并会抛出一个异常 RejectedExecution
CallerRunsPolicy调用者执行,让传递任务的线程执行此任务
Discard0ldestPolicy放弃队列中时间最长的任务,不会抛出异常
DiscardPolicy 直接放弃新的任务,不会抛出异常
线程池的工作原理
任务放置在工作队列中
1>池中是否有空闲的线程,如果有,,让该线程执行任务
2>如果没有空闲的线程,判断池中的线程数量有没有达到核心线程数
3 if 没有达到核心线程数 传件新的线程执行任务,直到填满核心线程数
else if 如果已经达到,优先在队列中存储,直到队列填满
4工作队列填满后再添加新的任务,是否达到最大线程数,
如果没有,创建新的线程执行任务 直到填满最大线程数
5>已经填满最大线程数,队列也已经填满,没有空闲线程,就执行回绝策略
线程池中的线程达到(超过)核心线程数,超出的数量会根据存活时间,进行销毁、直到数量达到核心线程数
如果线程的数量少于核心线程数则不会消亡
java中内置线程池对象
Executors
可以根据工作任务创建线程,如果没有空闲的线程就创建新的线程 线程存货时间6o秒
Executors.newCachedThreadPool();
设置最大线程数量
Executors.newFixedThreadPool(10);
提供定时运行的处理方案
Executors.newScheduledThreadPool(10);
创建一个单个线程的线程池 保障任务队列完全按照顺序执行
Executors.newSingleThreadExecutor();