观看“尚硅谷”相关视频自己记录的笔记!
class Ticket { public int number = 30; public synchronized void sale() { if (number > 0) { System.out.println(Thread.currentThread().getName() + " : 卖出 : " + (number--) + " ,剩下 : " + number); } } } public class SaleTicket { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 30; i++) { ticket.sale(); } } }, "AA").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 30; i++) { ticket.sale(); } } }, "BB").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 30; i++) { ticket.sale(); } } }, "CC").start(); } }
class Ticket { public int number = 30; private final ReentrantLock lock = new ReentrantLock(); public void sale() { lock.lock(); try { if (number > 0) { System.out.println(Thread.currentThread().getName() + " : 卖出 : " + (number--) + " ,剩下 : " + number); } } finally { lock.unlock(); } } } public class LSaleTicket { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(() -> { for (int i = 0; i < 30; i++) { ticket.sale(); } }, "AA").start(); new Thread(() -> { for (int i = 0; i < 30; i++) { ticket.sale(); } }, "BB").start(); new Thread(() -> { for (int i = 0; i < 30; i++) { ticket.sale(); } }, "CC").start(); } }
**在哪里等待就在哪里醒来!!** **加上while()循环!** class share { private int num = 0; public synchronized void incr() throws InterruptedException { while (num != 0) { this.wait(); } num++; System.out.println(Thread.currentThread().getName() + " :: " + num); this.notifyAll(); } public synchronized void decr() throws InterruptedException { while (num != 1) { this.wait(); } num--; System.out.println(Thread.currentThread().getName() + " :: " + num); this.notifyAll(); } } public class ThreadDemo1 { public static void main(String[] args) { share s = new share(); new Thread(() -> { for (int i = 0; i < 30; i++) { try { s.incr(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "AA").start(); new Thread(() -> { for (int i = 0; i < 30; i++) { try { s.decr(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "BB").start(); new Thread(() -> { for (int i = 0; i < 30; i++) { try { s.decr(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "CC").start(); new Thread(() -> { for (int i = 0; i < 30; i++) { try { s.decr(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "DD").start(); } }
**AA卖5次票** **BB卖10次票** **CC卖15次票** **执行十轮** class ShareResource { private int flag = 1; private Lock lock = new ReentrantLock(); private Condition c1 = lock.newCondition(); private Condition c2 = lock.newCondition(); private Condition c3 = lock.newCondition(); public void print5(int loop) throws InterruptedException { lock.lock(); try { while (flag != 1) { c1.await(); } for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " :: " + i + " :轮数: " + loop); } flag = 2; c2.signal(); } finally { lock.unlock(); } } public void print10(int loop) throws InterruptedException { lock.lock(); try { while (flag != 2) { c2.await(); } for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + " :: " + i + " :轮数: " + loop); } flag = 3; c3.signal(); } finally { lock.unlock(); } } public void print15(int loop) throws InterruptedException { lock.lock(); try { while (flag != 3) { c3.await(); } for (int i = 0; i < 15; i++) { System.out.println(Thread.currentThread().getName() + " :: " + i + " :轮数: " + loop); } flag = 1; c1.signal(); } finally { lock.unlock(); } } } public class ThreadDemo3 { public static void main(String[] args) { ShareResource shareResource = new ShareResource(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { shareResource.print5(i); } catch (InterruptedException e) { e.printStackTrace(); } } }, "AA").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { shareResource.print10(i); } catch (InterruptedException e) { e.printStackTrace(); } } }, "BB").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { shareResource.print15(i); } catch (InterruptedException e) { e.printStackTrace(); } } }, "CC").start(); } }
Java中的每一个对象都可以作为锁。 对于普通同步方法,锁是当前实例对象。 对于静态方法,锁是当前类的Class对象。 对于同步方法块,锁是synchonized括号里配置的对象。
公平锁 :阳光普照 效率低 非公平锁 :线程饿死 效率高
synchronized(隐式)和lock(显式)都是可重入锁 :是否需要手动上锁解锁操作! lock实现可重入锁 new Thread(() -> { try { lock.lock(); System.out.println(Thread.currentThread().getName()); try { lock.lock(); System.out.println(Thread.currentThread().getName()); }finally { lock.unlock(); } }finally { lock.unlock(); } }, "AA").start();
static Object a = new Object(); static Object b = new Object(); public static void main(String[] args) { new Thread(()->{ synchronized (a) { System.out.println(Thread.currentThread().getName() + "持有锁a,试图获取锁b"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (b) { System.out.println(Thread.currentThread().getName() + "获取锁b"); } } },"A").start(); new Thread(()->{ synchronized (b) { System.out.println(Thread.currentThread().getName() + "持有锁b,试图获取锁a"); synchronized (a) { System.out.println(Thread.currentThread().getName() + "获取锁a"); } } },"B").start(); }
先执行子线程,最后汇总! class MyThread1 implements Runnable { @Override public void run() { return; } } class MyThread2 implements Callable { @Override public Integer call() throws Exception { return 200; } } public class Demo01 { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<Integer> task1 = new FutureTask<Integer>(new MyThread2()); FutureTask<Integer> task2 = new FutureTask<Integer>(() -> { System.out.println(Thread.currentThread().getName() + " come in callable"); return 1024; }); new Thread(task2,"lucy").start(); while(!task2.isDone()) { System.out.println("wait..."); } System.out.println(task2.get()); System.out.println(task2.get()); //不用等待,直接获取! System.out.println(Thread.currentThread().getName() + " come over"); } }
所有同学离开之后,班长锁门!!! public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(6); for(int i = 1; i <= 6;i++) { new Thread(()->{ System.out.println(Thread.currentThread().getName() + " 号同学离开了教室"); latch.countDown(); },String.valueOf(i)).start(); } latch.await(); System.out.println(Thread.currentThread().getName() + " 班长锁门走人了!"); }
所有条件实现之后,然后干。。。。 public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(number, () -> { System.out.println("***********七颗龙珠已经集齐,可以召唤神龙!"); }); for (int i = 1; i <= 7; i++) { new Thread(() -> { try { System.out.println(Thread.currentThread().getName() + " 星龙珠获得"); cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); } }
public static void main(String[] args) { //设置许可数量 Semaphore semaphore = new Semaphore(3); //模拟六辆汽车 for (int i = 1; i <= 6; i++) { new Thread(() -> { try { //抢占 semaphore.acquire(); System.out.println(Thread.currentThread().getName() + " 号车抢到了车位!"); //设置随机停车时间 TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println(Thread.currentThread().getName() + " 号车-离开了车位"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } }, String.valueOf(i)).start(); } }
读写锁 :一个资源可以被多个读线程访问,或者可以被一个写线程访问,但是不能同时存在读写线程。读写互斥,读读共享!
ReentrantReadWriteLock
读读可以共享,提升性能!
同时进行读操作!
缺点 :(1)造成锁饥饿,一直读,没有写操作。
(2)读时候,不能写,只有读完成之后,才可以写,写操作可以读。
//资源类 class MyCache { //创建map集合 private volatile Map<String, Object> map = new HashMap<>(); private ReadWriteLock lock = new ReentrantReadWriteLock(); //存数据 public void put(String key, Object value) throws InterruptedException { lock.writeLock().lock(); System.out.println(Thread.currentThread().getName() + " 正在写 " + key); TimeUnit.MICROSECONDS.sleep(300); map.put(key, value); System.out.println(Thread.currentThread().getName() + " 写完了 " + key); lock.writeLock().unlock(); } //取数据 public Object get(String key) throws InterruptedException { lock.readLock().lock(); Object result = null; System.out.println(Thread.currentThread().getName() + " 正在取 " + key); TimeUnit.MICROSECONDS.sleep(300); result = map.get(key); System.out.println(Thread.currentThread().getName() + " 取完了 " + key); lock.readLock().unlock(); return result; } } public class ReadAndWriteDemo { //创建线程存数据 public static void main(String[] args) { MyCache cache = new MyCache(); for (int i = 1; i <= 5; i++) { final int num = i; new Thread(() -> { try { cache.put(num + "", num + ""); } catch (InterruptedException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); } try { TimeUnit.MICROSECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } //创建线程取数据 for (int i = 1; i <= 5; i++) { final int num = i; new Thread(() -> { try { cache.get(num + ""); } catch (InterruptedException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); } } }
读写锁降级
写锁 -> 读锁 -> 写锁释放 -> 读锁释放 ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock(); ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock(); //获取写锁 writeLock.lock(); System.out.println("---write"); //获取读锁 readLock.lock(); System.out.println("---read"); //释放写锁 writeLock.unlock(); //释放读锁 readLock.unlock();