论坛首页 Java企业应用论坛

最简单高效的tryLock

浏览 18517 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-09-23   最后修改:2010-09-23
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author asme2u
 */
public class Lock {

    private AtomicBoolean lock = new AtomicBoolean(true);

    public boolean tryLock() {
        return lock.compareAndSet(true, false);
    }

    public void unlock() {
        lock.set(true);
    }

}

 

原理:CAS

 

优点:

     速度快,约是ReentrantLock的2-3倍

 

 缺点:

     需JDK5.0+

     无条件对象且不可重入

     未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock

 

适用场景:

    不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候

 

我的应用场景:

    最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右

   发表时间:2010-09-24  
能说说怎么用嘛,写个简单例子
0 请登录后投票
   发表时间:2010-09-24  
很有创造力,可是
>>>     速度快,约是ReentrantLock的2-3倍
怎么得出来的呢?论据呢。。。。。
0 请登录后投票
   发表时间:2010-09-24  
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???

你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。
0 请登录后投票
   发表时间:2010-09-24  
hellojinjie 写道
很有创造力,可是
>>>     速度快,约是ReentrantLock的2-3倍
怎么得出来的呢?论据呢。。。。。

 

 

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author asme2u
 */
public class TestLock {
	
	private static long c = 0;
	public static void main(String[] args) {
		final Lock l = new Lock();
//		final ReentrantLock l = new ReentrantLock();
		Thread t1 = new Thread() {
			public void run() {
				for (int i = 0; i < 100000000;) {
					if (l.tryLock()) {
						c++;
						i++;
						l.unlock();
					}
				}
			}
		};
		Thread t2 = new Thread() {
			public void run() {
				for (int i = 0; i < 100000000;) {
					if (l.tryLock()) {
						c++;
						i++;
						l.unlock();
					}
				}
			}
		};
		long t = System.currentTimeMillis();
		Thread t3 = new Thread() {
			public void run() {
				for (int i = 0; i < 100000000;) {
					if (l.tryLock()) {
						c++;
						i++;
						l.unlock();
					}
				}
			}
		};
		t1.start();
		t2.start();
		t3.start();
		try {
			t1.join();
			t2.join();
			t3.join();
		} catch (InterruptedException e) {
		}
		System.out.println(c);
		System.out.println(System.currentTimeMillis() - t);
	}

}

 

 

在我的破笔记本上,单核的,分别用连个锁,一个跑了35秒,一个跑了14秒

0 请登录后投票
   发表时间:2010-09-24  
hellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???

你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。

我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高

 

0 请登录后投票
   发表时间:2010-09-24  
asme2u 写道
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author asme2u
 */
public class Lock {

    private AtomicBoolean lock = new AtomicBoolean(true);

    public boolean tryLock() {
        return lock.compareAndSet(true, false);
    }

    public void unlock() {
        lock.set(true);
    }

}

 

原理:CAS

 

优点:

     速度快,约是ReentrantLock的2-3倍

 

 缺点:

     需JDK5.0+

     无条件对象且不可重入

     未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock

 

适用场景:

    不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候

 

我的应用场景:

    最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右

 

 

你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?

 

ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。

 

 

0 请登录后投票
   发表时间:2010-09-24  
mercyblitz 写道
asme2u 写道
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author asme2u
 */
public class Lock {

    private AtomicBoolean lock = new AtomicBoolean(true);

    public boolean tryLock() {
        return lock.compareAndSet(true, false);
    }

    public void unlock() {
        lock.set(true);
    }

}

 

原理:CAS

 

优点:

     速度快,约是ReentrantLock的2-3倍

 

 缺点:

     需JDK5.0+

     无条件对象且不可重入

     未获取锁时直接调用unlock不抛IllegalMonitorStateException所以代码必须严格保证获取锁后才能调用unlock

 

适用场景:

    不需要条件对象且当ReentrantLock的tryLock影响了你的性能的时候

 

我的应用场景:

    最近项目中通信程序中的客户端的socket长连接的连接池,客户端使用连接具有高并发但占用连接时间非常短的特点,使用这个类代替ReentrantLock,性能提高了3倍左右

 

 

你这个有线程安全问题呢,怎么保证在tryLock 和unlock之间的线程安全(状态一直性)?

 

ReentrantLock 是利用Thread 队列,只有独占线程看到共享资源,pack其他线程,待操作完毕,下一个线程unpack继续操作。同时还有JVM底层的操作。

 

 

如果任何线程使用都遵守tryLock返回true后再去unlock,不会有线程安全问题的,compareAndSet是个原子操作

0 请登录后投票
   发表时间:2010-09-24   最后修改:2010-09-24
asme2u 写道

ellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???

你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。

我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高



看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好
0 请登录后投票
   发表时间:2010-09-24  
hellojinjie 写道
asme2u 写道

ellojinjie 写道
性能应该只与线程执有锁的时间和多少个线程竞争该锁有关,,为什么会和线程如何得到锁有关???

你用tryLock,应该是自旋锁这一类的吧,在我的单核的CPU上,恐怕也不会有什么性能的提高。。。

我实际应用场景是高并发,短占用,如果你应用场景从获取锁到释放锁需要很长的时间,性能不会有多少提高



看来是ReentrantLock 里的tryLock太耗时了,才会使得用AtomicBoolean实现的Lock性能比ReentryLock好

正解,只有符合锁占用的时间与获取锁的时间可比拟时,这个类才有意义,所以我列出了适用场景。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics