• Java并发 aqs


    AQS:AbstractQueuedSynchronizer

    一、AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器。

    二、原理:AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。

    原理图:

    三、学习路线图。大量的应用在j.u.c下的各个基础类和工具栏,构成Java并发包的基础。

     四、1、有一个重要的状态标志——state,该属性是一个int值,表示对象的当前状态。三个protected final的方法来改变state的值,分别是:getState、setState(int)、compareAndSetState(int, int)。

     private volatile int state;
    
        /**
         * Returns the current value of synchronization state.
         * This operation has memory semantics of a {@code volatile} read.
         * @return current state value
         */
        protected final int getState() {
            return state;
        }
    
        /**
         * Sets the value of synchronization state.
         * This operation has memory semantics of a {@code volatile} write.
         * @param newState the new state value
         */
        protected final void setState(int newState) {
            state = newState;
        }
    

      

       2、AQS定义两种资源共享方式

    • Exclusive(独占):只有一个线程能执行,如ReentrantLock。又可分为公平锁和非公平锁:

      • 公平锁:按照线程在队列中的排队顺序,先到者先拿到锁
      • 非公平锁:当线程要获取锁时,无视队列顺序直接去抢锁,谁抢到就是谁的
    • Share(共享):多个线程可同时执行,如Semaphore/CountDownLatch。Semaphore、CountDownLatCh、 CyclicBarrier、ReadWriteLock 。

       

    // exclusive mode
    protected boolean tryAcquire(int arg) {
            throw new UnsupportedOperationException();
        }
     protected boolean tryRelease(int arg) {
            throw new UnsupportedOperationException();
        }
    
    
    // shared mode共享模式
    protected int tryAcquireShared(int arg) {
            throw new UnsupportedOperationException();
        }
     protected boolean tryReleaseShared(int arg) {
            throw new UnsupportedOperationException();
        }
    

    3、用到了模板设计模式

    五、同步工具类

    CountDownLatch

    倒数计时。是一个同步工具类,用来协调多个线程之间的同步。这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。

    public class CountDownLatchDemo implements Runnable {
    
    	static final CountDownLatch latch = new CountDownLatch(10);
    	static final CountDownLatchDemo demo = new CountDownLatchDemo();
    
    	@Override
    	public void run() {
    		// 模拟检查任务
    		try {
    			Thread.sleep(new Random().nextInt(20) * 100);
    			System.out.println("check complete");
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		} finally {
    			// 计数减一
    			// 放在finally避免任务执行过程出现异常,导致countDown()不能被执行
    			latch.countDown();
    		}
    	}
    
    	public static void main(String[] args) throws InterruptedException {
    		ExecutorService exec = Executors.newFixedThreadPool(10);
    		for (int i = 0; i < 10; i++) {
    			exec.submit(demo);
    		}
    
    		// 等待检查
    		latch.await();
    
    		// 发射火箭
    		System.out.println("Fire!");
    		// 关闭线程池
    		exec.shutdown();
    	}
    
    }
    

    Semaphore 

    synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。

    不错的博文:https://blog.csdn.net/lxltmac/article/details/84871929

    https://segmentfault.com/a/1190000016885682

  • 相关阅读:
    Http协议和Tomcat服务器
    类加载器与反射
    线程安全
    String、Stringbuffer、Stringbuilder三者之间的区别
    iOS 开发,工程中如何混合使用 ARC 和非ARC
    dll的静态调用、动态调用
    Qt安装—搭建VS2008+QT开发环境
    C++中的引用与指针的区别
    SVN分支与合并
    (补充知识)DLL 中 .DEF文件的使用
  • 原文地址:https://www.cnblogs.com/luoa/p/11330603.html
Copyright © 2020-2023  润新知