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:3122474382set:begin2015-03-22 10:35:3122474382set: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:1830771886set:end2015-03-22 10:51:2314718739set: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:164699264set:begin2015-03-22 10:54:164699264set:end2015-03-22 10:54:21
读写锁允许同时读,但不允许读写同时进行