synchronized 读写同步
这是一道面试题,不少人也遇到了。
要求:1.读-读 不用线程同步。2.读-写 要求线程同步,写的时候不能读。3.写-写同步。写的时候不能写。
java lock读写锁是好的处理方案。这里不说了。但人家问的是synchronized 读写同步。
假设两个方法,write() ,read();
1.和3.很好理解也很现实。
通过思考:write()必须是同步的,全部对象都要同步。那这里须要设计成静态的。若是不静态的,保证每次同步都是一个锁。
其次 read() 以前要栓查write同步锁,但又没有对应方法能够检查。想到的是 再写一个栓查方法。这个方法与write使用同一个同步锁(设计在同一个类,同时静态)。但这个方法是空的,什么也不作。
因此设计成以下代码:
package test; public class Test { public void read() { canRead(); System.out.println(Thread.currentThread().getName() + "-->>begain read"); System.out.println(Thread.currentThread().getName() + "-->>reading"); try { Thread.sleep(1100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "-->>read end"); } public static synchronized void canRead() { } public static synchronized void write() { System.out.println(Thread.currentThread().getName() + "-->>begain write"); canRead(); System.out.println(Thread.currentThread().getName() + "-->>writing"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "-->>writing end"); return; } public static void main(String[] args) { Test test = new Test(); Thread t = new Thread(new Runnable() { @Override public void run() { while (true) { test.read(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }); t.setName("read_thread_1"); t.start(); Thread t1 = new Thread(new Runnable() { @Override public void run() { while (true) { test.read(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }); t1.setName("read_thread_2"); t1.start(); Thread t2 = new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Test.write(); } } }); t2.setName("write_thread"); t2.start(); Thread t3 = new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Test.write(); } } }); t3.setName("write_thread_2"); t3.start(); } }
运行结果以下,经过结果分析,读线程是穿插的,不存在同步。写线程都是完整执行过程,是同步的。java
read_thread_1-->>begain read面试
read_thread_1-->>readingide
read_thread_2-->>begain read学习
read_thread_2-->>readingspa
read_thread_1-->>read end线程
read_thread_2-->>read end设计
read_thread_1-->>begain readcode
read_thread_1-->>reading对象
read_thread_2-->>begain readblog
read_thread_2-->>reading
read_thread_1-->>read end
read_thread_2-->>read end
write_thread-->>begain write
write_thread-->>writing
write_thread-->>writing end
read_thread_2-->>begain read
read_thread_2-->>reading
read_thread_1-->>begain read
read_thread_1-->>reading
write_thread_2-->>begain write
write_thread_2-->>writing
write_thread_2-->>writing end
read_thread_2-->>read end
read_thread_1-->>read end
read_thread_2-->>begain read
read_thread_2-->>reading
read_thread_1-->>begain read
read_thread_1-->>reading
read_thread_2-->>read end
read_thread_1-->>read end
write_thread-->>begain write
write_thread-->>writing
write_thread-->>writing end
write_thread_2-->>begain write
write_thread_2-->>writing
write_thread_2-->>writing end
read_thread_1-->>begain read
read_thread_1-->>reading
read_thread_2-->>begain read
read_thread_2-->>reading
read_thread_1-->>read end
read_thread_2-->>read end
read_thread_1-->>begain read
read_thread_1-->>reading
read_thread_2-->>begain read
read_thread_2-->>reading
write_thread-->>begain write
write_thread-->>writing
read_thread_1-->>read end
read_thread_2-->>read end
write_thread-->>writing end
write_thread_2-->>begain write
write_thread_2-->>writing
write_thread_2-->>writing end
read_thread_2-->>begain read
read_thread_2-->>reading
read_thread_1-->>begain read
read_thread_1-->>reading
read_thread_2-->>read end
read_thread_1-->>read end
read_thread_2-->>begain read
read_thread_1-->>begain read
read_thread_1-->>reading
read_thread_2-->>reading
write_thread-->>begain write
write_thread-->>writing
这个代码冗余部分是要执行一个空方法,目前尚未想到其它方法,有大牛有好办法能够留言互相学习。
代码 bug :开始写的时候尚未读完的线程。会致使错误。
-----待改进-----------