【多线程】使用ReentrantLock类 - 1

在Java多线程中,可以使用synchronized关键字来实现线程之间的同步互斥,但在JDK1.5中新增加了ReentrantLock类也能达到同样的效果,并且在扩展功能上也更加强大,比如具有嗅探锁定、多路分支通知等功能,而且在使用上也比synchronized更加灵活。
public class TestReentrantLock {
    public static void main(String[] args) {
        MyService myService = new MyService();
        ThreadD a = new ThreadD(myService);
        ThreadD b = new ThreadD(myService);
        ThreadD c = new ThreadD(myService);
        ThreadD d = new ThreadD(myService);
        ThreadD e = new ThreadD(myService);
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
    }
}

class ThreadD extends Thread {
    private MyService myService;

    public ThreadD(MyService myService) {
        this.myService = myService;
    }

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

class MyService {
    private Lock lock = new ReentrantLock();

    public void testMethod() {
        try {
            lock.lock();
            for (int i = 0; i < 3; i++) {
                System.out.println("Thread name is " + Thread.currentThread().getName() + " " + (i+1));
            }
            Thread.sleep(1000);
            lock.unlock();
        } catch (InterruptedException ex) {
            Logger.getLogger(MyService.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

结果如下:
run:
Thread name is Thread-0 1
Thread name is Thread-0 2
Thread name is Thread-0 3
Thread name is Thread-1 1
Thread name is Thread-1 2
Thread name is Thread-1 3
Thread name is Thread-2 1
Thread name is Thread-2 2
Thread name is Thread-2 3
Thread name is Thread-4 1
Thread name is Thread-4 2
Thread name is Thread-4 3
Thread name is Thread-3 1
Thread name is Thread-3 2
Thread name is Thread-3 3

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

public class TestReentrantLock {

    public static void main(String[] args) {
        MyService myService = new MyService();
        ThreadD d = new ThreadD(myService);
        d.setName("D");
        d.start();
        
        ThreadDD dd = new ThreadDD(myService);
        dd.setName("DD");
        dd.start();
        
        ThreadE e = new ThreadE(myService);
        e.setName("E");
        e.start();
        
        ThreadEE ee = new ThreadEE(myService);
        ee.setName("EE");
        ee.start();
    }
}

class ThreadD extends Thread {

    private MyService myService;

    public ThreadD(MyService myService) {
        this.myService = myService;
    }

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

}

class ThreadDD extends Thread {

    private MyService myService;

    public ThreadDD(MyService myService) {
        this.myService = myService;
    }

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

}

class ThreadE extends Thread {

    private MyService myService;

    public ThreadE(MyService myService) {
        this.myService = myService;
    }

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

}

class ThreadEE extends Thread {

    private MyService myService;

    public ThreadEE(MyService myService) {
        this.myService = myService;
    }

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

}

class MyService {

    private Lock lock = new ReentrantLock();

    public void methodD() {
        try {
            lock.lock();
            System.out.println("Excute methodD, Thread name is " + Thread.currentThread().getName());
            Thread.sleep(1000);
            lock.unlock();
        } catch (InterruptedException ex) {
            Logger.getLogger(MyService.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void methodE() {
        try {
            lock.lock();
            System.out.println("Excute methodE,Thread name is " + Thread.currentThread().getName());
            Thread.sleep(1000);
            lock.unlock();
        } catch (InterruptedException ex) {
            Logger.getLogger(MyService.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

运行结果是:
Excute methodD, Thread name is D
Excute methodD, Thread name is DD
Excute methodE,Thread name is E
Excute methodE,Thread name is EE

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

猜你喜欢

转载自margaret0071.iteye.com/blog/2368080
今日推荐