1. 程式人生 > >java學習筆記(四) java多執行緒-使用ReentrantLock實現同步

java學習筆記(四) java多執行緒-使用ReentrantLock實現同步

1. 使用ReentrantLock

在JDK1.5中新增的ReentrantLock類在擴充套件功能上比synchronized更加強大,比如具有嗅探鎖定、多路分支通知等功能,使用比synchronized更加靈活。

1.1 使用ReentrantLock實現同步:測試1

1.1.1 MyService類

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

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

1.1.2 MyThread類

public class MyThread extends Thread
{ private MyService service; public MyThread(MyService service){ super(); this.service = service; } @Override public void run(){ service.testMethod(); } }

1.1.3 Test類

public class Test {
    public static void main(String[] args) {

        MyService service =
new MyService(); MyThread t1 = new MyThread(service); MyThread t2 = new MyThread(service); MyThread t3 = new MyThread(service); t1.start(); t2.start(); t3.start(); } }

1.1.4 執行結果

ThreatName = Thread-0 0
ThreatName = Thread-0 1
ThreatName = Thread-0 2
ThreatName = Thread-1 0
ThreatName = Thread-1 1
ThreatName = Thread-1 2
ThreatName = Thread-2 0
ThreatName = Thread-2 1
ThreatName = Thread-2 2

1.2 使用ReentrantLock實現同步:測試2

1.2.1 MyService類

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyService {

    private Lock lock = new ReentrantLock();

    public void methodA(){
        try {
            lock.lock();
            System.out.println("methodA begin, ThreadName = " + Thread.currentThread().getName());

            Thread.sleep(3000);

            System.out.println("methodA end  , ThreadName = " + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void methodB(){
        try {
            lock.lock();
            System.out.println("methodB begin, ThreadName = " + Thread.currentThread().getName());

            Thread.sleep(3000);

            System.out.println("methodB end  , ThreadName = " + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

1.2.2 ThreadA

public class ThreadA extends Thread{
    private MyService service;

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

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

1.2.3 ThreadAA

public class ThreadAA extends Thread{
    private MyService service;

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

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

1.2.4 ThreadB

public class ThreadB extends Thread{
    private MyService service;

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

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

1.2.5 Test

public class Test {
    public static void main(String[] args) throws InterruptedException {
        MyService service = new MyService();

        //A thread
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        //AA thread
        ThreadAA aa = new ThreadAA(service);
        aa.setName("AA");
        aa.start();
        Thread.sleep(1000);

        //B thread
        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();
    }
}

1.2.6 執行結果

methodA begin, ThreadName = A
methodA end  , ThreadName = A
methodA begin, ThreadName = AA
methodA end  , ThreadName = AA
methodB begin, ThreadName = B
methodB end  , ThreadName = B

結果說明呼叫lock.lock()的執行緒就持有了“物件監視器”,其他執行緒只能等待鎖被釋放,效果和使用synchronized一樣,執行緒之間還是順序執行的。