读写锁
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Data { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public synchronized void set(){ System.out.println(Thread.currentThread().hashCode() + "set:begin" + sdf.format(new Date())); try{ Thread.sleep(5000); }catch(Exception e){ }finally{ System.out.println(Thread.currentThread().hashCode() + "set:end" +sdf.format(new Date())); } } public synchronized void get(){ System.out.println(Thread.currentThread().hashCode() + "set:begin" + sdf.format(new Date())); try{ Thread.sleep(5000); }catch(Exception e){ }finally{ System.out.println(Thread.currentThread().hashCode() + "set:end" +sdf.format(new Date())); } } }
public class Worker extends Thread { Data data; boolean read; public Worker(Data data, boolean read) { this.data = data; this.read = read; } public void run() { if (read) data.get(); else data.set(); } }
public class ReadWriteLockDemo { public static void main(String args[]) { Data data = new Data(); Worker thread1 = new Worker(data, true); Worker thread2 = new Worker(data, true); thread1.start(); thread2.start(); } }
上面的代码使用synchronized锁,用synchronized修饰的方法只能同时被一个线程访问,于是代码中两个线程要依次执行,结果如下
8637543set:begin2015-03-22 10:35:26
8637543set:end2015-03-22 10:35:31
22474382set:begin2015-03-22 10:35:31
22474382set:end2015-03-22 10:35:36
下面使用读写锁,只需要修改Data类就可以了
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Data { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ReadWriteLock lock = new ReentrantReadWriteLock(); Lock read = lock.readLock(); Lock write = lock.writeLock(); public void set(){ write.lock(); System.out.println(Thread.currentThread().hashCode() + "set:begin" + sdf.format(new Date())); try{ Thread.sleep(5000); }catch(Exception e){ }finally{ System.out.println(Thread.currentThread().hashCode() + "set:end" +sdf.format(new Date())); write.unlock(); } } public void get(){
read.lock() System.out.println(Thread.currentThread().hashCode() + "set:begin" + sdf.format(new Date())); try{ Thread.sleep(5000); }catch(Exception e){ }finally{ System.out.println(Thread.currentThread().hashCode() + "set:end" +sdf.format(new Date()));
read.unlock() } } }
同时读,结果
30771886set:begin2015-03-22 10:51:18
14718739set:begin2015-03-22 10:51:18
30771886set:end2015-03-22 10:51:23
14718739set:end2015-03-22 10:51:23
两个线程同时读取数据,同时执行结束,没有限制。
public class ReadWriteLockDemo { public static void main(String args[]) { Data data = new Data(); Worker thread1 = new Worker(data, false); Worker thread2 = new Worker(data, true); thread1.start(); thread2.start(); } }
第一个线程写, 第二个线程读
8637543set:begin2015-03-22 10:54:11
8637543set:end2015-03-22 10:54:16
4699264set:begin2015-03-22 10:54:16
4699264set:end2015-03-22 10:54:21
读写锁允许同时读,但不允许读写同时进行