标签:多线程 并发 读写锁 lock readwritelock
JDK1.5之后有提供了另一种加锁方式Lock锁。Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的Condition 对象。
锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不过,某些锁可能允许对共享资源并发访问,如ReadWriteLock 的读取锁。
synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问,但却强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。
而lock加锁之后必须我们搜索释放掉锁:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
synchronized可以改写为如下:
package andy.thread.test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Zhang,Tianyou
* @version 2014年11月8日 下午11:30:10
*/
public class ThreadLockTest {
public static void main(String[] args) {
A a = new A();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a.printfA(Thread.currentThread().getName()
+ "hello, my is A");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a.printfA(Thread.currentThread().getName()
+ "hello, my is B");
}
}
}).start();
}
static class A {
// 定义Lock锁
Lock lock = new ReentrantLock();
public void printfA(String name) {
lock.lock();// 添加lock锁
try {
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();
} finally {
lock.unlock();// 无论加锁内容是否执行 都要释放锁
}
}
}
}
1 读取锁可以由多个 reader 线程同时保持
2 写入锁是独占的。
ReadWriteLock rwl = new ReentrantReadWriteLock();
一、读锁操作
rwl.readLock().lock();
rwl.readLock().unlock();
二、写锁操作
rwl.writeLock().lock();
rwl.writeLock().unlock();
实现读写所如下:
package andy.thread.test;
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @author Zhang,Tianyou
* @version 2014年11月8日 下午11:44:01
*/
public class ReadWriteLockTest {
public static void main(String[] args) {
final A a = new A();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
a.get();
}
}
}.start();
new Thread() {
public void run() {
while (true) {
a.put(new Random().nextInt(10000));
}
}
}.start();
}
}
}
class A {
private Object data = null;// 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
ReadWriteLock rwl = new ReentrantReadWriteLock();
public void get() {
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()
+ " be ready to read data!");
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName()
+ "have read data :" + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.readLock().unlock();
}
}
public void put(Object data) {
rwl.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()
+ " be ready to write data!");
Thread.sleep((long) (Math.random() * 1000));
this.data = data;
System.out.println(Thread.currentThread().getName()
+ " have write data: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.writeLock().unlock();
}
}
}
Thread-0 be ready to read data! Thread-4 be ready to read data! Thread-2 be ready to read data! Thread-0have read data :null Thread-2have read data :null Thread-4have read data :null Thread-1 be ready to write data! Thread-1 have write data: 5730 Thread-1 be ready to write data! Thread-1 have write data: 7997 Thread-1 be ready to write data! Thread-1 have write data: 2306 Thread-1 be ready to write data! Thread-1 have write data: 8944 Thread-1 be ready to write data! Thread-1 have write data: 8039 Thread-1 be ready to write data! Thread-1 have write data: 6844 Thread-1 be ready to write data! Thread-1 have write data: 2969 Thread-1 be ready to write data!
标签:多线程 并发 读写锁 lock readwritelock
原文地址:http://blog.csdn.net/fengshizty/article/details/40932145