0
点赞
收藏
分享

微信扫一扫

Lock的使用


Lock的使用
1.使用ReentrantLock类
    * 在java多线程中,可以使用synchronized关键字来实现线程之间同步互斥,但在JDK1.5中新增加了ReentrantLock类
        也能达到同样的效果,并且再扩展功能上也更加强大,比如有嗅探锁定,多路分支通知等功能,而且在使用上也比
        synchronized更加的灵活。


    *使用ReentrantLock实现同步

        举个栗子:

public class MyService {
private Lock lock=new ReentrantLock();
public void testMethod(){
lock.lock();
for(int i=0;i<5;i++){
System.out.println("ThreadName="+Thread.currentThread().getName()+(""+(i+1)));
}
lock.unlock();
}
}

public class MyThread extends Thread {
private MyService myService;
public MyThread(MyService myService){
super();
this.myService=myService;
}

@Override
public void run() {
myService.testMethod();
}
}

public class Run {
public static void main(String[] args) {
MyService service = new MyService();
MyThread a1 = new MyThread(service);
MyThread a2 = new MyThread(service);
MyThread a3 = new MyThread(service);
MyThread a4 = new MyThread(service);
MyThread a5 = new MyThread(service);
a1.start();
a2.start();
a3.start();
a4.start();
a5.start();
}
}

很简单,使用lock加锁,unlock解锁

    * 使用Condition实现等待/通知
        关键字synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待/通知模式,类ReentrantLock也
        可以实现同样的功能,但需要借助于Condition对象。Condition类是在JDK5中出现的技术,使用它有更好的灵活性,
        比如可以实现多路通知功能,也就是在一个Lock对象里面可以创建多个Condition(即对象监视器)实例,线程对象可以
        注册在指定的Condition中,从而可以有选择性地进行线程通知,在调度线程上更加灵活。
        注意:在调用condition.await()方法前,必须用lock.lock()代码获取同步监视器。


        * 使用Condition实现等待/通知

举个栗子


public class MyService {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();

public void await() {
try {
lock.lock();
System.out.println(" await时间为" + System.currentTimeMillis());
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public void signal() {
try {
lock.lock();
System.out.println("signal时间为 " + System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
}

public class ThreadA extends Thread {
private MyService service;

public ThreadA(MyService service) {
super();
this.service = service;
}

@Override
public void run() {
service.await();
}
}

public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.start();
Thread.sleep(3000);
service.signal();
}
}



*使用多个Condition实现通知部分线程

public class MyService {
private Lock lock = new ReentrantLock();
public Condition conditionA = lock.newCondition();
public Condition conditionB = lock.newCondition();

public void awaitA() {
try {
lock.lock();
System.out.println("begin awaitA时间为" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());
conditionA.await();
System.out.println(" end awaitA时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public void awaitB() {
try {
lock.lock();
System.out.println("begin awaitB时间为 " + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
conditionB.await();
System.out.println(" end awaitB时间为 " + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public void signalAll_A() {
try {
lock.lock();
System.out.println(" signalAll_A时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
conditionA.signalAll();
} finally {
lock.unlock();
}
}

public void signalAll_B() {
try {
lock.lock();
System.out.println(" signalAll_B时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
conditionB.signalAll();
} finally {
lock.unlock();
}
}

}


测试后,只有线程A被唤醒了。使用ReentrantLock对象可以唤醒指定种类的线程,这是控制部分线程行为的方便方式。

    *公平锁与非公平锁
        公平与非公平锁:锁Lock分为 "公平锁”和"非公平锁",公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,
        即先来先得的FIFO先进先出顺序。而非公平锁就是一种获取锁的抢占机制,是随机获得锁的,和公平锁不一样的就是先来的
        不一定先得到锁,这个方式可能造成某些线程一直拿不到锁,结果也就是不公平的了。
        lock =new ReentrantLock(true);//公平锁
        lock =new ReentrantLock(false);//非公平锁

举报

相关推荐

0 条评论