Jetty源码-自旋锁的实现

Jetty自旋锁解析
本文介绍了Jetty项目中自旋锁(SpinLock)的设计与实现。Jetty自旋锁适用于保护非常短小且非阻塞的关键代码段,通过原子类的CAS操作实现线程间的竞争,有效防止了线程在等待锁时放弃CPU资源。文章还提供了测试代码示例。

      最近在浏览jetty9.3的源码,具体代码见github  https://github.com/eclipse/jetty.project

      本篇文章主要介绍jetty源码中 jetty-util模块的线程部分中自旋锁。jetty线程模块中,线程池的实现没有什么特别的部分,都是对JDK中ThreadPoolExecutor的封装。其中有个自旋锁的实现,个人感觉挺好的。

      在介绍之前,先介绍JDK1.7引入的一个AutoCloseable接口,本人也是初次才知道这个接口。该接口的作用主要是凡是实现了该接口的类,通过可以在try(){}-catch语法里,自动调用释放资源的方法close()。以下是具体的Demo

public class TestAutoClose implements AutoCloseable {
    public void method(){
        System.out.println("invoke method............");
    }
    @Override
    public void close() throws Exception {
        System.out.println("close resource.............");
    }
    public static void main(String[]args){
        try(TestAutoClose testAutoClose=new TestAutoClose()){
            testAutoClose.method();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //程序会自动调用close()方法,我们可以在里面实现释放资源的逻辑
    }
}

   

        现在步入正题jetty SpinLock:

        该自旋锁设计目的主要是为了保护非常短小的关键代码段。线程在获取到该自旋锁之前会一直自旋, 因此被该自旋锁保护的代码,必须非常简单,没有阻塞。因为在各个线程竞争获取该锁的时候, 会一直自旋,不会放弃cpu, 该锁主要通过原子类的CAS,来获取锁。

       以上是对jetty SpinLock的注释的具体翻译:

     This is a lock designed to protect VERY short sections of critical code.  Threads attempting to take the lock will spin  forever until the lock is available, thus it is important that the code protected by this lock is extremely simple and non blocking. The reason for this lock is that it prevents a thread from giving up a CPU core when contending for the lock.

 * try(SpinLock.Lock lock = spinlock.lock())

 * {

 *   // something very quick and non blocking

 * }

public class SpinLock {
    private final AtomicReference<Thread> _lock = new AtomicReference<>(null);
    private final Lock _unlock = new Lock();
    public Lock lock()
    {
        Thread thread = Thread.currentThread();
        while(true)
        {
            //通过CAS操作来获取锁
            if (!_lock.compareAndSet(null,thread))
            {   //不支持重入
                if (_lock.get()==thread)
                    throw new IllegalStateException("SpinLock is not reentrant");
                continue;
            }
            return _unlock;
        }
    }
    public boolean isLocked()
    {
        return _lock.get()!=null;
    }
    public boolean isLockedThread()
    {
        return _lock.get()==Thread.currentThread();
    }
    public class Lock implements AutoCloseable
    {   //在try catch块中可以自动释放锁,不需要显示手动调用 。
        @Override
        public void close()
        {
            _lock.set(null);
        }
    }
}

        下面是我写的测试代码

public class TestSpinLock implements Runnable {
    private SpinLock spinLock=new SpinLock();
    public int counter=0;
    private void incr(){
        try(SpinLock.Lock lock=spinLock.lock()) {
            counter++;
        }
    }
    public static void main(String[]args) throws InterruptedException {
        TestSpinLock testSpinLock=new TestSpinLock();
        ExecutorService executorService= Executors.newCachedThreadPool();
        //提交三个任务,来同时计数
        executorService.submit(testSpinLock);
        executorService.submit(testSpinLock);
        executorService.submit(testSpinLock);
        //等待任务完成
        executorService.shutdown();
        executorService.awaitTermination(1000, TimeUnit.SECONDS);
        System.out.println(testSpinLock.counter);
    }
    @Override
    public void run() {
        for(int i=0;i<1000000;i++){
            incr();
        }
    }
}

       个人感觉jetty实现的这个SpinLock很精简,很容易理解。

      转发请注明来源:http://my.oschina.net/robinyao/blog/400712

转载于:https://my.oschina.net/robinyao/blog/400712

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值