public class Outputter { private Lock lock = new ReentrantLock(); public void output(String name){ lock.lock(); //得到锁 try{ for(int i = 0; i < name.length();i++){ System.out.print(name.charAt(i)); } }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock(); //释放锁 } } }
public class LockTest { public static void main(String[] args) { final Outputter outputter = new Outputter(); new Thread(){ public void run(){ outputter.output("Chinaese "); } }.start(); new Thread(){ public void run(){ outputter.output("Chinaese "); } }.start(); new Thread(){ public void run(){ outputter.output("Chinaese "); } }.start(); } }
上述代码可以解决线程安全问题,效果和synchronized一样。不同的是,synchronized修饰的方法或者代码块执行完后自动释放锁,而lock需要手动释放锁。
对于数据区的内容,我们要做到 读写互斥 写写互斥 读读不互斥(这里先考虑读读互斥)
/** * 显然不满足我们的需求 * 我们需要实现的是:读写互斥 写写互斥 读读不互斥 * @author hp * */public class ReadWriteLockTest { public static void main(String[] args) { final Data data = new Data(); for(int i = 0;i<3;i++){ new Thread(new Runnable(){ public void run() { for(int i = 0; i< 5;i++){ data.set(new Random().nextInt(30)); } } }).start(); } for(int i = 0;i < 3;i++){ new Thread(new Runnable(){ public void run() { for(int i = 0;i< 5;i++){ data.get(); } } }).start(); } } /*static class Data{ private int data; public void set(int data){ System.out.println(Thread.currentThread().getName()+"准备写数据"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } this.data = data; System.out.println(Thread.currentThread().getName()+"写入数据"+data); } public void get(){ System.out.println(Thread.currentThread().getName()+"准备读取数据"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"读取"+this.data); } }*/ static class Data{ private int data; private ReadWriteLock rwl = new ReentrantReadWriteLock(); public void set(int data){ rwl.writeLock().lock(); try { System.out.println(Thread.currentThread().getName()+"准备写数据"); Thread.sleep(20); this.data = data; System.out.println(Thread.currentThread().getName()+"写入数据"+data); } catch (InterruptedException e) { e.printStackTrace(); }finally{ rwl.writeLock().unlock(); } } public void get(){ rwl.readLock().lock(); try { System.out.println(Thread.currentThread().getName()+"准备读取数据"); Thread.sleep(20); System.out.println(Thread.currentThread().getName()+"读取"+this.data); } catch (InterruptedException e) { e.printStackTrace(); }finally{ rwl.readLock().unlock(); } } } }