(二)线程同步_4---使用Lock同步代码块

使用Lock同步代码块

Java提供了另外一种机制去同步代码块,这种机制比synchronized关键字更加灵活也更加强大,这种机制就是基于Lock接口和相关的实现类(如ReentrantLock),这种机制有已下几个优点:

它使得同步代码块能够可以以更加灵活的方式组织;使用synchronized关键字将会不得不放弃以更加灵活的结构组织方式处理同步代码块,而Lock接口可以使我们能够充分利用这种优势;

  • Lock接口相比synchronized关键字提供了更多的功能,比如tryLock(),这个方法被其它线程调用,获得锁对象;使用synchronized关键字,当线程A尝试执行同步代码块,而线程B正在执行,那么A将会挂起,直到B执行完; 而是用Lock接口,调用tryLock将返回Boolean类型,可以控制当前线程是要挂起还是继续执行下面的代码;
  • Lock接口允许读和写操作分离;多个读线程或一个写线程;
  • Lock接口有比synchronized更好的性能;

 下面展示一个简单的例子

动手实现

1.创建PrintQueue

public class PrintQueue {
    private final Lock queueLock=new ReentrantLock();

    public void printJob(Object document) {
        queueLock.lock();
        try {
            Long duration=(long)(Math.random()*10000);
            System.out.printf("%s:PrintQueue: Printing a Job during %d seconds\n",Thread.currentThread().getName(),(duration/1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            queueLock.unlock();
        }
    }
}

2.创建一个Job

public class Job implements Runnable {
    private PrintQueue printQueue;

    public Job(PrintQueue printQueue) {
        this.printQueue = printQueue;
    }

    @Override
    public void run() {
        System.out.printf("%s: Going to print a document\n", Thread.currentThread().getName());
        printQueue.printJob(new Object());
        System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        PrintQueue printQueue=new PrintQueue();
        Thread thread[]=new Thread[10];
        for (int i=0; i<10; i++){
            thread[i]=new Thread(new Job(printQueue),"Thread "+ i);
        }

        for (int i=0; i<10; i++){
            thread[i].start();
        }
    }
}

要点

在lock之后一定要解锁

简单源码分析

Lock的接口中的所有方法:

void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();


Lock接口的主要实现类是ReentrantLock,该类是Lock类的增强实现,比如该类中有
public final boolean hasQueuedThread(Thread thread);
public final int getQueueLength();
protected Collection<Thread> getQueuedThreads();
public boolean hasWaiters(Condition condition);
public int getWaitQueueLength(Condition condition);
这些方法可以获取线程运行时的更多信息;

这里注意 tryLock()和lock()方法的区别,tryLock方法直接返回,而lock方法可能会使线程挂起;更加要注意的是使用Lock一定要注意不要造成DeadLock;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值