JUC学习
JUC是java.util.concurrent包 并发编程的工具包
并发、并行
并发:多线程操作一个资源
并行:多人一起走
并发编程的本质:充分利用cpu的资源
线程的几个状态
新建 运行 堵塞 等待 销毁
wait/sleep区别
1.来自不同的类 wait->object sleep->Thread 注:实际开发中线程休眠不要用Thread.sleep(5000); 建议使用juc的工具类 TimeUnit.DAYS.sleep(1);//睡1天 TimeUnit.SECONDS.sleep(2);//睡2秒 2.关于锁的释放 wait会释放锁 sleep抱着锁睡了不会释放 3.使用的范围不同 wait:必须在同步代码块中使用 sleep:可以在任何地方睡 //4.是否需要捕获异常 //wait不需要捕获异常 sleep必须捕获异常
Lock锁(重点)
Lock的实现类: ReentrantLock //可重入锁(常用) ReentrantReadWriteLock.ReadLock //读锁 ReentrantReadWriteLock.WriteLock //写锁 例子: class Ticket22{ private int num=50; Lock lock = new ReentrantLock(); public void sale(){ lock.lock();//加锁 try { if (num>0){ System.out.println(Thread.currentThread().getName()+"卖出了"+(num--)+"张票,剩"+num); } }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock();//解锁 } } } 主要步骤: //1.lock加锁 //2.执行方法体 //3.解锁
synchronized锁和Lock的区别
1.synchronized是java内置关键字 Lock是一个java类 2.synchronized无法判断锁的状态 Lock可以判断是否获取到锁 3.synchronized锁会自动解锁 Lock必须手动解锁 4.synchronized锁 线程1获得锁后 线程2只会傻傻的等待 Lock锁线程1获得锁后 线程2不一定会等待(lock.tryLock();) 5.synchronized可重入锁 不能中断 非公平 Lock锁 可重入锁 可以判断锁 非公平(可自己设置) 6.synchronized适合锁少量同步代码 Lock适合锁大量的同步代码
ReadWriteLock(读写锁)
用ReentrantLock锁也可以满足读写接口的线程安全
但若用ReentrantLock锁 读接口也只能跑一个线程了 效率不够高
ReentrantReadWriteLock锁比ReentrantLock锁更加细粒化
在写线程没跑时可以允许多个读线程跑
加锁解锁的写法与ReentrantLock基本一致
private volatile Map map = new HashMap();//volatile多线程读取到变量最新 private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //写入 public void put(String key,Object val){ readWriteLock.writeLock().lock();//写锁锁定 try { map.put(key,val); System.out.println("写入"); }catch (Exception e){ e.printStackTrace(); }finally { readWriteLock.writeLock().unlock(); } } //读取 public void get(String key){ readWriteLock.readLock().lock();//读锁 try { System.out.println(map.get(key)); }catch (Exception e){ e.printStackTrace(); }finally { readWriteLock.readLock().unlock(); } }