thread-最佳时间
wait-notify
wait被阻塞后其是会释放锁的,并且需要在sychronized范围内使用
sychronized(lock){
while(!条件){
lock.wait();
}
}
sychronized(lock){
lock.notifyAll();
}
join 模式保护性暂停
public final synchronized void join(final long millis)
throws InterruptedException {
if (millis > 0) {
if (isAlive()) {
final long startTime = System.nanoTime();
long delay = millis;
do {
wait(delay);
} while (isAlive() && (delay = millis -
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0);
}
} else if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
throw new IllegalArgumentException("timeout value is negative");
}
}
LockSupport park()&&unpark(thread)
Unsafe中定义的,主要是通过判断_counter()是否为一,当调用unpark(thread)时,会将_count()设置为一,当调用park()时,会判断_count(),如果为一则放行,并设置_counter()为0,否则阻塞当前线程
每一个线程都会一个parker对象,由_counter、_cond、_mutex组成
Thread thread = new Thread(() -> {
System.out.println("线程开始");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程暂停");
LockSupport.park();
System.out.println("线程执行完");
});
thread.start();
Thread.sleep(1000);
System.out.println("执行唤醒");
LockSupport.unpark(thread);
线程活跃性
线程活跃性主要是死锁、活锁、饥饿
线程尝试去获取多把锁时出现的问题
活锁:线程之间相互改变对方的结束条件
饥饿:低优先级的线程无法获取锁
ReentrantLock
可重入 可打断 锁超时 可设置为公平锁
解决死锁,使用ReentrantLock中的trylock解决死锁问题
公平锁:谁先进入阻塞队列,谁先得到cpu时间片,可以使用new ReentrantLokc(true)使用,公平锁会降低并发度
reentrantLock.await()相对于thread.wait()其支持多个条件变量,可操作性更好
基础代码块
lock.lock();
try{
}finally{
lock.unlock();
}
可重入
private static ReentrantLock reentrantLock =new ReentrantLock();
public static void main(String[] args) {
reentrantLock.lock();
try {
System.out.println("main");
t1();
}finally {
reentrantLock.unlock();
}
}
private static void t1(){
reentrantLock.lock();
try {
System.out.println("t1");
}finally {
reentrantLock.unlock();
}
}
可打断
Thread t = new Thread(() -> {
try {
reentrantLock.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("没有获取锁");
reentrantLock.unlock();
return;
}
try {
System.out.println("获取到了锁");
} finally {
reentrantLock.unlock();
}
});
t.start();
reentrantLock.lock();
Thread.sleep(2000L);
t.interrupt();
blaking
private static boolean isTure =false;
sychronized(this){
if(isTure){
return ;
}
isTure =true;
}
单例模式
public final class Test5 {
public static volatile Test5 t =null;
public static Test5 getTest5() {
if (t!=null){
return t;
}
synchronized (Test5.class){
if (t!=null){
return t;
}
t=new Test5();
return t;
}
}
}
无锁并发
cas+volatile
cas如果cpu核心数够的话不需要上下文切换,sychronized多线程竞争时一定会产生上下文切换
cas是乐观锁,无阻塞,改的时候进行比较,sychronized是悲观锁直接禁止修改
AtomicBoolean AtomicInteger AtomicReference
public static void updateAndSet(AtomicInteger at){
while (true) {
int i1 = at.get();
if (at.compareAndSet(i1, multiNum(i1))) {
break;
}
}
}
public static Integer multiNum(Integer num){
return num *100;
}
ABA问题
为感知其它线程反复修改,可以增加版本号,进行compareandSwap操作是不仅需要对值进行判断也需要对版本号进行判断 只有版本号相等的时候才能进行更新
AtomicStampedReference 版本号
AtomicMarkableReference boolean值
AtomicIntegerArray
AtomicReferenceArray