多线程之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!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。