多线程中ReentrantLock的使用

来源:互联网 发布:iphone6sp设置铃声软件 编辑:程序博客网 时间:2024/06/05 10:18

多线程中ReentrantLock的使用

一.使用ReentrantLock类

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

1.1使用ReentrantLock类实现同步:测试1

新建类MyService.java:

package service;

 

import java.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

 

public class MyService {

 

         privateLock lock = new ReentrantLock();

 

         publicvoid testMethod() {

                   lock.lock();

                   for(int i = 0; i < 5; i++) {

                            System.out.println("ThreadName="+ Thread.currentThread().getName()

                                               +(" " + (i + 1)));

                   }

                   lock.unlock();

         }

 

}

调用ReentrantLock对象的lock()方法获取锁,调用unlock方法释放锁。

新建MyThread.java:

package extthread;

 

import service.MyService;

 

public class MyThread extends Thread {

 

         privateMyService service;

 

         publicMyThread(MyService service) {

                   super();

                   this.service= service;

         }

 

         @Override

         publicvoid run() {

                   service.testMethod();

         }

}

运行类Run.java代码如下:

package test;

 

import service.MyService;

import extthread.MyThread;

 

public class Run {

 

         publicstatic void main(String[] args) {

 

                   MyServiceservice = new MyService();

 

                   MyThreada1 = new MyThread(service);

                   MyThreada2 = new MyThread(service);

                   MyThreada3 = new MyThread(service);

                   MyThreada4 = new MyThread(service);

                   MyThreada5 = new MyThread(service);

 

                   a1.start();

                   a2.start();

                   a3.start();

                   a4.start();

                   a5.start();

 

         }

 

}

        程序运行结果如下图,从运行结果看,当前线程打印完毕之后将锁进行释放,其他线程才可以继续打印。线程打印的数据是分组打印,因为当前线程已经持有锁,但线程之间打印的顺序是随机的。

         

 

1.2使用ReentrantLock类实现同步:测试2

新建MyService.java:

package service;

 

import java.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

 

public class MyService {

 

         privateLock lock = new ReentrantLock();

 

         publicvoid methodA() {

                   try{

                            lock.lock();

                            System.out.println("methodAbegin ThreadName="

                                               +Thread.currentThread().getName() + " time="

                                               +System.currentTimeMillis());

                            Thread.sleep(5000);

                            System.out.println("methodA  end ThreadName="

                                               +Thread.currentThread().getName() + " time="

                                               +System.currentTimeMillis());

                   }catch (InterruptedException e) {

                            e.printStackTrace();

                   }finally {

                            lock.unlock();

                   }

         }

 

         publicvoid methodB() {

                   try{

                            lock.lock();

                            System.out.println("methodBbegin ThreadName="

                                               +Thread.currentThread().getName() + " time="

                                               +System.currentTimeMillis());

                            Thread.sleep(5000);

                            System.out.println("methodB  end ThreadName="

                                               +Thread.currentThread().getName() + " time="

                                               +System.currentTimeMillis());

                   }catch (InterruptedException e) {

                            e.printStackTrace();

                   }finally {

                            lock.unlock();

                   }

         }

 

}

新建ThreadA.java:

package extthread;

 

import service.MyService;

 

public class ThreadA extends Thread {

 

         privateMyService service;

 

         publicThreadA(MyService service) {

                   super();

                   this.service= service;

         }

 

         @Override

         publicvoid run() {

                   service.methodA();

         }

}

新建ThreadAA.java:

package extthread;

 

import service.MyService;

 

public class ThreadAA extends Thread {

 

         privateMyService service;

 

         publicThreadAA(MyService service) {

                   super();

                   this.service= service;

         }

 

         @Override

         publicvoid run() {

                  service.methodA();

         }

}

新建ThreadB.java:

package extthread;

 

import service.MyService;

 

public class ThreadB extends Thread {

 

         privateMyService service;

 

         publicThreadB(MyService service) {

                   super();

                   this.service= service;

         }

 

         @Override

         publicvoid run() {

                   service.methodB();

         }

}

新建ThreadBB.java:

package extthread;

 

import service.MyService;

 

public class ThreadBB extends Thread {

 

         privateMyService service;

 

         publicThreadBB(MyService service) {

                   super();

                   this.service= service;

         }

 

         @Override

         publicvoid run() {

                   service.methodB();

         }

}

运行类Run.java:

package test;

 

import service.MyService;

import extthread.ThreadA;

import extthread.ThreadAA;

import extthread.ThreadB;

import extthread.ThreadBB;

 

public class Run {

 

         publicstatic void main(String[] args) throws InterruptedException {

                   MyServiceservice = new MyService();

 

                   ThreadAa = new ThreadA(service);

                   a.setName("A");

                   a.start();

                   ThreadAAaa = new ThreadAA(service);

                   aa.setName("AA");

                   aa.start();

 

                   Thread.sleep(100);

 

                   ThreadBb = new ThreadB(service);

                   b.setName("B");

                   b.start();

                  

                   ThreadBBbb = new ThreadBB(service);

                   bb.setName("BB");

                   bb.start();

 

         }

 

}

    程序运行结果如下:

    

    此例子说明,调用lock.lock()代码的线程就持有了“对象监视器”,其他线程只有等待锁被释放是再次争抢。效果和使用synchronized关键字一样,线程之间还是顺序执行的。

 

 

 

 

 

 

原创粉丝点击