多线程之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();// 无论加锁内容是否执行 都要释放锁
			}

		}
	}

}



Lock 还提供了读写锁ReadWriteLock:

读取锁可以由多个 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!





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