1。写一个自己的锁
package lock.mylock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* 实现自己的独占锁
* @author Administrator
*
*/
public class SelfLock implements Lock {
//定义一个内部类,自定义同步器
private static class Sync extends AbstractQueuedSynchronizer{
/**
*
*/
private static final long serialVersionUID = 1L;
// 判定当前线程是否处于占用锁的状态
@Override
protected boolean isHeldExclusively() {
//其实这里只需要返回当前的state状态是否为1,1表示已经获取到锁,0则表示没有获取到
return getState()==1;
}
//实现获得锁方法
@Override
protected boolean tryAcquire(int arg) {
//compareAndSetState();使用CAS设置当前状态,该方法能够保证状态设置的原子性。
// 这个方法的实现需要查询当前状态是否允许获取,然后再进行获取(使用compareAndSetState来做)
//如果compareAndSetState的返回值为TRUE,说明state修改成功并且成功获得了锁
//@1参数期望值
//@2参数更新新值
if(compareAndSetState(0, 1)){
//把当前拿到锁的线程设定为当前线程,表示独占这个锁
//判断成功后设置排他,表示当前这个锁我拿到了
setExclusiveOwnerThread(Thread.currentThread());
//表示当前拿到了这把锁
return true;
}
//判断是否是自己拿的锁,用于重入情况
else if(getExclusiveOwnerThread()==Thread.currentThread()){
//如果是就+1
setState(getState()+1);
return true;
}
//那么大部分线程拿锁不成功返回false,没有拿到锁的线程返回false继续返回队列进行排队
return false;
}
//实现释放锁方法
@Override
protected boolean tryRelease(int arg) {
//判断重入的情况,如果当前线程不是我自己就抛出异常
if(getExclusiveOwnerThread()!=Thread.currentThread()){
throw new IllegalMonitorStateException();
}
if(getState() ==0){
//如果状态为0说明状态是异常的,则抛出错误
throw new IllegalMonitorStateException();
}
//设置状态-1
setState(getState()-1);
//如果减1了之后是0 了,说明没有线程访问,把当前拿锁的线程置为null
if(getState()==0){
//如果没有抛出异常则手动释放
setExclusiveOwnerThread(null);
}
return true;
}
}
// 仅需要将操作代理到Sync上即可
private final Sync sync = new Sync();
@Override
public void lock() {
System.out.println(Thread.currentThread()+" read get lock");
sync.acquire(1);
System.out.println(Thread.currentThread().getName()+" already got lock");
}
@Override
public void lockInterruptibly() throws InterruptedException {
// TODO Auto-generated method stub
}
@Override
public Condition newCondition() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean tryLock() {
// TODO Auto-generated method stub
return sync.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
// TODO Auto-generated method stub
return false;
}
@Override
public void unlock() {
System.out.println(Thread.currentThread()+" read release lock");
sync.release(1);
System.out.println(Thread.currentThread().getName()+" already release lock");
}
}
2.测试自己的锁
package lock.mylock;
import java.util.concurrent.locks.Lock;
import lock.mycountdownlatch.MySelfLock;
import util.SleepTools;
public class TestMyLock {
public void test(){
//创建一个自己的锁对象
final Lock lock = new SelfLock();
//写一个方法局部类继承线程
class Worker extends Thread{
@Override
public void run() {
//拿锁后打印
lock.lock();
System.out.println(Thread.currentThread().getName());
try{
SleepTools.second(1);
}finally {
//做完事情后解锁
lock.unlock();
}
}
}
//4个线程执行
for(int i = 0 ; i < 10 ; i ++){
Worker w = new Worker();
w.start();
}
}
public static void main(String[] args) {
TestMyLock testMyLock = new TestMyLock();
testMyLock.test();
}
}