天天看點

lock

 Lock是java.util.concurrent.locks包下的接口,Lock 實作提供了比使用synchronized 方法和語句可獲得的更廣泛的鎖定操作,它能以更優雅的方式處理線程同步問題,實作一下和sychronized一樣的效果,代碼如下:

package Lock;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class LockTest {

public static void main(String[] args) {

final Outputter1 output = new Outputter1();

new Thread() {

public void run() {

output.output("zhangsan");

};

}.start();

output.output("lisi");

}

class Outputter1 {

private Lock lock = new ReentrantLock();// 鎖對象

public void output(String name) {

// TODO 線程輸出方法

lock.lock();// 得到鎖

try {

for(int i = 0; i < name.length(); i++) {

System.out.print(name.charAt(i));

System.out.println("");

} finally {

lock.unlock();// 釋放鎖

這樣就實作了和sychronized一樣的同步效果,需要注意的是,用sychronized修飾的方法或者語句塊在代碼執行完之後鎖自動釋放,而用Lock需要我們手動釋放鎖,是以為了保證鎖最終被釋放(發生異常情況),要把互斥區放在try内,釋放鎖放在finally内。

        如果說這就是Lock,那麼它不能成為同步問題更完美的處理方式,下面要介紹的是讀寫鎖(ReadWriteLock),我們會有一種需求,在對資料進行讀寫的時候,為了保證資料的一緻性和完整性,需要讀和寫是互斥的,寫和寫是互斥的,但是讀和讀是不需要互斥的,這樣讀和讀不互斥性能更高些:

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockTest {

public static void main(String[] args) {

final Data data = new Data();

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

new Thread(new Runnable() {

public void run() {

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

data.set(new Random().nextInt(30));

}

}

}).start();

}

data.get();

}

}

class Data {

private int data;// 共享資料

private ReadWriteLock rwl = new ReentrantReadWriteLock();

public void set(int data) {

rwl.writeLock().lock();// 取到寫鎖

try {

System.out.println(Thread.currentThread().getName() + "準備寫入資料");

try {

Thread.sleep(20);

} catch (InterruptedException e) {

e.printStackTrace();

}

this.data = data;

System.out.println(Thread.currentThread().getName() + "寫入" + this.data);

} finally {

rwl.writeLock().unlock();// 釋放寫鎖

}

public void get() {

rwl.readLock().lock();// 取到讀鎖

System.out.println(Thread.currentThread().getName() + "準備讀取資料");

System.out.println(Thread.currentThread().getName() + "讀取" + this.data);

rwl.readLock().unlock();// 釋放讀鎖

繼續閱讀