Synchronized: 系统锁 重量级锁
涉及内容,锁优化,自旋锁(轻量级锁),锁升级
也是可重入锁
ReentrantLock 可以 替代 Synchronized.
使用方法:
try中lock(), finally中unlock()
- ReentrantLock是手动加锁解锁,Synchronized是自动的。比较灵活synchronized如果拿不到锁就阻塞wait,但ReentrantLock有tryLock方法,可以尝试拿 锁。
使用方法
boolean locked = false; try { locked = lock.tryLock(5, TimeUnit.SECONDS); System.out.println("m2 ..." + locked); } catch (InterruptedException e) { e.printStackTrace(); } finally { if(locked) lock.unlock(); }注意:这里tryLock() 拿不到锁不是进异常ReentrantLock还可以设置为公平锁
ReentrantLock lock=new ReentrantLock(true);
这里默认参数:false(非公平)
公平锁就是有一个线程等待的队列,非公平锁上来直接抢,不管有没有队列,公平就是判断有没有队列,有队列就排队。
Latch闩锁 countDouwnLatch 倒数的门锁
就是线程执行完了
使用方法Thread[] threads = new Thread[100]; CountDownLatch latch = new CountDownLatch(threads.length); for(int i = 0; i < threads.length; i++) { threads[i] = new Thread(() -> { int result = 0; for(int j = 0; j < 10000; j++) result += j; latch.countDown(); }); } for(int i = 0; i < threads.length; i++) { threads[i].start(); } try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); }CyclicBarrier
Barrier 栅栏 CyclicBarrier 循环栅栏
new CyclicBarrier()参数中的第一个参数就是线程数量,就是什么时候线程达到这个数量,就继续执行
CyclicBarrier 和 CountDownLatch的区别:
CountDownLatch是执行完就减一(可以是一个线程多次执行),CyclicBarrier是当线程数达到规定数量时才执行下·
使用方法:
CyclicBarrier barrier = new CyclicBarrier(20, new Runnable() { @Override public void run() { System.out.println("满人,发车"); } }); for(int i=0; i<100; i++) { new Thread(()->{ try { barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }).start(); }Phaser
Phase 阶段
类似于一个又一个的barrier
可以解决遗传算法
使用方法:
MarriagePhaser phaser = new MarriagePhaser();
phaser.bulkRegister([中间是自己定义的一共多少个线程]);
phaser.arriveAndDeregister();
phaser.arriveAndAwaitAdvance();
类需要继承Phaser然后重写onAdvance() 方法
顾名思义:读写锁
可以锁读,可以锁写
往死了重要!
共享锁:
共享,就是多个人可以共享一把锁,翻译成人话就是有这个锁的就是自家人,就可以执行。其中读锁就是共享锁,意思就是不同线程读的时候用的锁就是同一把锁,就是读线程拿到锁的时候只要是读线程就可以访问。
排他锁:
写锁就是排他锁,就是自己一个人用。其他写线程和读线程都不能用。(自私)
问:为什么不只给写上锁?
会出现脏读现象
使用方法:
static int number = 123; static ReentrantLock lock = new ReentrantLock(); static ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); static Lock readLock = readWriteLock.readLock(); static Lock writeLock = readWriteLock.writeLock(); private static void readMethod(Lock lock) { try { lock.lock(); Thread.sleep(500); System.out.println("read Method! "); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } private static void writeMethod(Lock lock, int n) { try { lock.lock(); number = n; Thread.sleep(500); System.out.println("write Method! "); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public static void main(String[] args) { T10_Exercise t = new T10_Exercise(); for (int i = 0; i < 18; i++) { new Thread(() -> readMethod(readLock)).start(); } for (int i = 0; i < 2; i++) { new Thread(() -> writeMethod(writeLock, 888)).start(); } }Semaphore
semaphore 信号
使用:
Semaphore s = new Semaphore(permits:2);//也可以设置为公平 true
s.acquire(); //拿到信号量,信号量数据–,减到为零就不能获取了
s.release(); //释放信号量,信号量数据++
使用场景:限流
小问题:
semaphore中permits是可以同时运行的线程一共有多少个,但有多少个线程在线程池中不管。
两个线程中交换数据使用(不同线程中的通信)
static Exchangerexchanger = new Exchanger<>(); public static void main(String[] args) { new Thread(()->{ String s = "T1"; try { s = exchanger.exchange(s); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + s); }, "t1").start(); new Thread(()->{ String s = "T2"; try { s = exchanger.exchange(s); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + s); }, "t2").start(); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)