赞
踩
sleep()&wait()
sleep(0)详细解读,建议深度理解下
(1)从使用者角度,sleep是Thread中的方法,wait()是Object()方法;
(2)从使用地方角度,sleep可以任意使用,而wait只能在sychronized代码块中使用。
(3)从释放锁的角度来说,sleep不会释放锁,他也不需要占用锁。而wait会释放锁(但是调用它的前提是当前线程占有锁);
(4)从唤醒角度来说,sleep在时间到了之后会自动进去可运行态。而wait()必须通过notify方法唤醒。
(5)他们都可以被interrupted()方法打断
(6)Thread.sleep(0)
Thread.Sleep(1000) 意思是在未来的1000毫秒内本线程不参与CPU竞争,1000毫秒过去之后,这时候也许另外一个线程正在使用CPU,那么这时候操作系统是不会重新分配CPU的,直到那个线程挂起或结束,即使这个时候恰巧轮到操作系统进行CPU 分配,那么当前线程也不一定就是总优先级最高的那个,CPU还是可能被其他线程抢占去。另外值得一提的是Thread.Sleep(0)的作用,就是触发操作系统立刻重新进行一次CPU竞争,竞争的结果也许是当前线程仍然获得CPU控制权,也许会换成别的线程获得CPU控制权。
wait(1000)表示将锁释放1000毫秒,到时间后如果锁没有被其他线程占用,则再次得到锁,然后wait方法结束,执行后面的代码,如果锁被其他线程占用,则等待其他线程释放锁。注意,设置了超时时间的wait方法一旦过了超时时间,并不需要其他线程执行notify也能自动解除阻塞,但是如果没设置超时时间的wait方法必须等待其他线程执行notify。

一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。读写锁比互斥锁允许对于共享数据更大程度的并发。每次只能有一个写线程,但是同时可以有多个线程并发地读数据。

(1)继承thread类,重写run()方法,太局限。
(2)实现runable()接口
(3)实现Callnable接口,重写call方法,带有返回值
(4)线程池的方式
为什么synchronized安全?
使用 javap -v 查看字节码文件发现,monitorenter 和 monitorexit 两个独有的指令。执行同步代码后首先要先执行 monitorenter 指令,退出的时候monitorexit 指令。使用Synchronized 进行同步,其关键就是必须要对对象的监视器 monitor 进行获取,当线程获取 monitor 后才能继续往下执行,否则就只能等待。而这个获取的过程是互斥的,即同一时刻只有一个线程能够获取到monitor。

volatile禁止指令重排:
“观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”
lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2)它会强制将对缓存的修改操作立即写入主存;
3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
CAS并发原语提现在Java语言中就是sun.miscUnSafe类中的各个方法。调用UnSafe类中的CAS方法,JVM会帮我实现CAS汇编指令.这是一种完全依赖于硬件 功能,通过它实现了原子操作。再次强调,由于CAS是一种系统原语,原语属于操作系统用于范畴,是由若干条指令组成,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许中断,也即是说CAS是一条原子指令,不会造成所谓的数据不一致的问题。
线程池
AbortPolicy:直接抛出异常,阻止系统正常运行。
CallerRunsPolicy :只要线程池未关闭,该策略直接在调用者线程中,运行当
前被丢弃的任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极
有可能会急剧下降。
DiscardOldestPolicy :丢弃最老的一个请求,也就是即将被执行的任务,并
尝试再次提交当前任务。
DiscardPolicy :该策略默默地丢弃无法处理的任务,不予任何处理。如果允
许任务丢失,这是最好的一种方案。
常用线程池:
FixedThreadPool 和 SingleThreadExecutor : 允许请求的队列⻓度为
Integer.MAX_VALUE,可能堆积⼤量的请求,从⽽导致 OOM。
CachedThreadPool 和 ScheduledThreadPool : 允许创建的线程数量为
Integer.MAX_VALUE,可能会创建⼤量线程,从⽽导致 OOM。
线程池大小的设定:
线程状态之间的转换

(1)Timer类,缺点,单个线程执行任务,当前一个任务出现问题时,会影响后续的任务 . (2)SpringBoot定时器:
(1)单线程,处理单个事件如果过慢,就会造成其他事件拥堵情况。
(2)线程池,单个线程只处理分发任务,具体执行流程交给线程池执行。这时候单个线程的分发可能会成为瓶颈,比如说我们有一万个连接,同时还有一万个正在写的事件。那么单线程的分发负载就会过大。
(3)主从模式,主select()负责处理连接,而从select()负责读写事件。支持高程度的并发。
公平锁:
公平锁自然是遵循 FIFO(先进先出)原则的,先到的线程会优先获取资源,后
到的会进行排队等待
优点:所有的线程都能得到资源,不会饿死在队列中。
缺点:吞吐量会下降,队列里面除了第一个线程,其他的线程都会阻塞,cpu
唤醒阻塞线程的开销大
非公平锁:
多个线程去获取锁的时候,会直接去尝试获取,获取不到,再去进入等待队列,
如果能获取到,就直接获取到锁。
优点:可以减少 CPU 唤醒线程的开销,整体的吞吐效率会高点,CPU 也不必取
唤醒所有线程,会减少唤起线程的数量。
缺点:你们可能也发现了,这样可能导致队列中间的线程一直获取不到锁或者
长时间获取不到锁
公平锁效率低原因:
公平锁要维护一个队列,后来的线程要加锁,即使锁空闲,也要先检查有没有
其他线程在 wait,如果有自己要挂起,加到队列后面,然后唤醒队列最前面线
程。这种情况下相比较非公平锁多了一次挂起和唤醒。
线程切换的开销,其实就是非公平锁效率高于公平锁的原因,因为非公平锁减
少了线程挂起的几率,后来的线程有一定几率逃离被挂起的开销。
Java 内存模型(Java Memory Model,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了 Java 程序在各种平台下对内存的访问都能保证效果一致的机制及规范。
JMM 是一种规范,是解决由于多线程通过共享内存进行通信时,存在的本地内
存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的
问题。目的是保证并发编程场景中的原子性、可见性和有序性。
所以,Java 内存模型,除了定义了一套规范,还提供了一系列原语,封装了底
层实现后,供开发者直接使用。我们前面提到,并发编程要解决原子性、有序性
和一致性的问题。
package pro_cum; public class sync { public static void main(String[] args) { Data data=new Data(); new Thread(()->{ for(int i=0;i<10;i++){ try { data.increase(); } catch (InterruptedException e) { e.printStackTrace(); } } },"A").start(); new Thread(()->{ for(int i=0;i<10;i++){ try { data.decrease(); } catch (InterruptedException e) { e.printStackTrace(); } } },"B").start(); new Thread(()->{ for(int i=0;i<10;i++){ try { data.increase(); } catch (InterruptedException e) { e.printStackTrace(); } } },"C").start(); new Thread(()->{ for(int i=0;i<10;i++){ try { data.decrease(); } catch (InterruptedException e) { e.printStackTrace(); } } },"D").start(); } } class Data{ private int num=0; public synchronized void increase() throws InterruptedException { while(num!=0){ this.wait(); } num++; System.out.println(Thread.currentThread().getName() + "值为:" + num); this.notifyAll(); } public synchronized void decrease() throws InterruptedException { while(num==0){ this.wait(); } num--; System.out.println(Thread.currentThread().getName() + "值为:" + num); this.notifyAll(); } }
package leetcode; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ABC { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); Runnable runa=new Runnable() { @Override public void run() { System.out.println("A"); //executorService.execute(this::run); } }; Runnable runb=new Runnable() { @Override public void run() { System.out.println("B"); //executorService.execute(this::run); } }; Runnable runc=new Runnable() { @Override public void run() { System.out.println("C"); //executorService.execute(this::run); } }; for(int i=0;i<10;i++){ executorService.execute(runa); executorService.execute(runb); executorService.execute(runc);} } }
package pro_cum; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LOCK { public static void main(String[] args) { Data1 data=new Data1(); new Thread(()->{ for(int i=0;i<10;i++){ data.printA(); } }).start(); new Thread(()->{ for(int i=0;i<10;i++){ data.printB(); } }).start(); new Thread(()->{ for(int i=0;i<10;i++){ data.printC(); } }).start(); } } class Data1{ private Lock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); private int num=1; public void printA(){ lock.lock(); try{ while(num!=1){ condition1.await(); } num++; System.out.println("A"); condition2.signal(); } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } public void printB(){ lock.lock(); try{ while(num!=2){ condition2.await(); } num++; System.out.println("B"); condition3.signal(); } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } public void printC(){ lock.lock(); try{ while(num!=3){ condition3.await(); } num=1; System.out.println("C"); condition1.signal(); } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。