多线程

gcc线程由 jvm 创建,是守护进程

创建线程方法1:

 

 创建线程方法2:

 

 静态代理:

 

 

 

 Lamda表达式:

 

例如:

 

 

例2:

 

 停止线程:

 

 循环1000次:1000.for

 

 yield:

仅仅是把当前线程放到就绪队列,不一定成功,下次可能还是它

 

 join:

 

 

线程状态:

 

 线程优先级:

 

 

 

例子:

 

 

 守护线程:

 

 例如:

用户线程执行完毕就结束了,不管守护线程

 线程同步:

 sleep能放大线程同步的问题

 synchronized:能锁住一个方法,成为同步方法,当一个线程还没调用完,另一个线程要调用只能阻塞

也可以通过同步块来实现,()表示锁住具体哪个对象,锁住谁就只能一个一个操作它,当进入到{}里面时,就把它锁住,当出了{}就将对它的锁释放:

 

 下面锁住了对象Account,具体的操作放在了{}

 例2:

注意ArrayList线程不安全

 

 copyonwritearraylist是线程安全的,不需要synchronized了:

 

若线程1获得被synchronize锁住的对象a,线程2获得被synchronize锁住的对象b,1想获得b,2想获得a,此时就死锁了

lock锁是显式的:

lock.lock()和lock.unlock()之间显式加锁和解锁

 

 

 synchronized和lock对比:

 

 wait,notify:

 

 

 生产者消费者问题解决:

 

 线程池:

 信号灯(设置标志位)解决生产者消费者:

JUC就是java.util .concurrent工具包的简称

 wait和sleep:

synchronized多线程例子:

 

 使用lock锁解决:

 

lock版的生产者和消费者(2个生产者,2个消费者,缓冲区1个格子):

condition是一个监视器

 改进:

通过使得进程在不同条件上等待,来按照某个顺序运行这些进程

 例1,由于有sleep 1,A线程就先运行了,且锁住了phone,B必须等A运行完了才能运行被synchronized修饰的方法,所以是先发短信:

 例2:hello没有被synchronized修饰,可以直接调用,先输出hello:

 

 例3:2个对象,各锁个的,先打电话:

 

 例4,加上static后,synchronized锁的是类,所以先发短信:

 

 例5,2个对象的类模板只有1个,还是先发短信:

 

 例6,锁的不是同一个东西,先打电话:

 

 list多线程不安全:

 

 并发修改异常:

 

 解决方案1用Vector,因为Vector的add有synchronized,3用CopyOnWriteArrayList,底层用的是lock,效率比synchronized高

 普通的Hashset也是线程不安全的:

 

 

Hashset底层:

 

 

 

 hashMap不安全:

 

 

 

使用callalbe开启线程,且得到返回值: 

 

 

 辅助类:CountDownLatch、CyclicBarrier、Semaphore

 CountDownLatch(减法计数器):

countdownLatch.awai():当计数值≠0,阻塞,利用这一点,可以让一堆小线程执行完,再执行main线程

 

 CyclicBarrier(加法计数器):

当有7个线程...await()时,才会调用方法体,召唤神龙成功

 

 

 

 Semaphore:信号量

new Semaphore(3):是设置信号量初始值

acquire:相当于P操作

release:相当于V操作

 

 

 读写锁:ReadWriteLock

公平锁和非公平锁

posted @ 2021-04-27 22:35  Jary霸  阅读(60)  评论(0)    收藏  举报