CAS
CAS
缺点:循环会耗时;一次性只能保持一个共享变量的原子性;ABA问题
| package juc.cas; |
| |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| public class CASDemo { |
| |
| |
| public static void main(String[] args) { |
| AtomicInteger atomicInteger = new AtomicInteger(2020); |
| |
| System.out.println(atomicInteger.compareAndSet(2020, 2021)); |
| System.out.println(atomicInteger.get()); |
| atomicInteger.getAndIncrement(); |
| |
| System.out.println(atomicInteger.compareAndSet(2020, 2021)); |
| System.out.println(atomicInteger.get()); |
| |
| } |
| } |
| package juc.cas; |
| |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| public class CASDemo { |
| |
| public static void main(String[] args) { |
| AtomicInteger atomicInteger = new AtomicInteger(2020); |
| |
| System.out.println(atomicInteger.compareAndSet(2020, 2021)); |
| System.out.println(atomicInteger.get()); |
| System.out.println(atomicInteger.compareAndSet(2021, 2020)); |
| System.out.println(atomicInteger.get()); |
| |
| |
| System.out.println(atomicInteger.compareAndSet(2020, 2022)); |
| System.out.println(atomicInteger.get()); |
| |
| } |
| } |
| package juc.cas; |
| |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.atomic.AtomicInteger; |
| import java.util.concurrent.atomic.AtomicStampedReference; |
| |
| public class CASDemo { |
| |
| public static void main(String[] args) { |
| |
| |
| AtomicStampedReference<Integer> atomicInteger = new AtomicStampedReference<>(1, 1); |
| |
| new Thread(()->{ |
| |
| System.out.println("A1->" + atomicInteger.getStamp()); |
| |
| try { |
| TimeUnit.SECONDS.sleep(2); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| |
| System.out.println(atomicInteger.compareAndSet(1, 2, |
| atomicInteger.getStamp(), atomicInteger.getStamp() + 1)); |
| System.out.println("A2->" + atomicInteger.getStamp()); |
| |
| System.out.println(atomicInteger.compareAndSet(2, 1, |
| atomicInteger.getStamp(), atomicInteger.getStamp() + 1)); |
| System.out.println("A3->" + atomicInteger.getStamp()); |
| |
| },"A").start(); |
| |
| |
| new Thread(()->{ |
| int stamp = atomicInteger.getStamp(); |
| System.out.println("B1->" + atomicInteger.getStamp()); |
| |
| try { |
| TimeUnit.SECONDS.sleep(2); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| |
| System.out.println(atomicInteger.compareAndSet(1, 6, stamp, stamp + 1)); |
| System.out.println("B2->" + atomicInteger.getStamp()); |
| |
| },"B").start(); |
| } |
| } |
Unsafe类
| @IntrinsicCandidate |
| public final int getAndAddInt(Object o, long offset, int delta) { |
| int v; |
| do { |
| v = getIntVolatile(o, offset); |
| } while (!weakCompareAndSetInt(o, offset, v, v + delta)); |
| return v; |
| } |
| public final int getAndIncrement() { |
| return U.getAndAddInt(this, VALUE, 1); |
| } |
各种锁的理解
- 公平锁:不能插队,必须先来后到
- 非公平锁:可以插队,默认都是非公平
| public ReentrantLock() { |
| sync = new NonfairSync(); |
| } |
| |
| public ReentrantLock(boolean fair) { |
| sync = fair ? new FairSync() : new NonfairSync(); |
| } |
- 可重入锁:拿到外面的锁,就可以拿到里面的锁,自动获得
| package juc.lock; |
| |
| public class Demo1 { |
| public static void main(String[] args) { |
| Phone phone = new Phone(); |
| new Thread(()->{ |
| phone.sms(); |
| }, "A").start(); |
| |
| new Thread(()->{ |
| phone.sms(); |
| }, "B").start(); |
| |
| |
| |
| |
| |
| |
| |
| } |
| } |
| |
| class Phone{ |
| public synchronized void sms(){ |
| System.out.println(Thread.currentThread().getName() + "sms"); |
| call(); |
| } |
| |
| public synchronized void call(){ |
| System.out.println(Thread.currentThread().getName() + "call"); |
| } |
| } |
| package juc.lock; |
| |
| import java.util.concurrent.locks.Lock; |
| import java.util.concurrent.locks.ReentrantLock; |
| |
| public class Demo2 { |
| public static void main(String[] args) { |
| Phone2 phone = new Phone2(); |
| new Thread(()->{ |
| phone.sms(); |
| }, "A").start(); |
| |
| new Thread(()->{ |
| phone.sms(); |
| }, "B").start(); |
| |
| |
| |
| |
| |
| |
| |
| } |
| } |
| |
| class Phone2{ |
| Lock lock = new ReentrantLock(); |
| |
| public void sms(){ |
| |
| lock.lock(); |
| try { |
| System.out.println(Thread.currentThread().getName() + "sms"); |
| call(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| lock.unlock(); |
| } |
| } |
| |
| public void call(){ |
| |
| lock.lock(); |
| try { |
| System.out.println(Thread.currentThread().getName() + "call"); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| lock.unlock(); |
| } |
| } |
| } |
| package juc.lock; |
| |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| public class MySpinlock { |
| AtomicReference<Thread> atomicReference = new AtomicReference<>(); |
| |
| public void myLock() { |
| Thread thread = Thread.currentThread(); |
| System.out.println(Thread.currentThread().getName() + " -> mylock"); |
| |
| |
| while (!atomicReference.compareAndSet(null, thread)){ |
| |
| } |
| } |
| |
| |
| public void myUnLock() { |
| Thread thread = Thread.currentThread(); |
| System.out.println(Thread.currentThread().getName() + " -> myUnlock"); |
| atomicReference.compareAndSet(thread, null); |
| } |
| |
| public static void main(String[] args) throws InterruptedException { |
| MySpinlock mySpinlock = new MySpinlock(); |
| new Thread(()->{ |
| mySpinlock.myLock(); |
| try { |
| TimeUnit.SECONDS.sleep(3); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| mySpinlock.myUnLock(); |
| } |
| }, "A").start(); |
| |
| TimeUnit.SECONDS.sleep(1); |
| |
| new Thread(()->{ |
| mySpinlock.myLock(); |
| try { |
| TimeUnit.SECONDS.sleep(3); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| mySpinlock.myUnLock(); |
| } |
| }, "B").start(); |
| |
| |
| |
| |
| |
| |
| |
| } |
| } |
- 死锁
- 使用“jps -l”定位进程号
- 使用“jstack 进程号”寻找死锁问题
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/14598312.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步