要求:
1. 线程x在读取共享内存时必须确保读取的内容可靠, 因此在读取过程中, Shared Memory存储的内容不能被其他线程改变.
2. 所有线程(无论读或写)无序且并发执行.
3. 线程x写内存Shared Memory时, 为保证其他线程读取的内容真实可靠, 在写操作未完成时, 不允许任何线程读取.
4. 当线程x读取Shared Memory时, 其他线程也可以读取.
5. 当线程x 写内存Shared Memory时, 未保证数据一致性, 其他线程不允许写.
我自己写的代码如下:
- Java code
public class MuitipleThread {public static void main(String[] args) {Buffer sharedLocation = new UnsynchronizedBuffer();Producer p = new Producer(sharedLocation); Consumer s = new Consumer(sharedLocation); for (int i = 1; i <= 20; i++) { int j = 0; j = (int) (Math.random() * 10 + 1); if (j <= 3) { Thread tdj = new Thread(p); tdj.start(); } else { Thread tdj = new Thread(s); tdj.start(); } }}interface Buffer { public void set();public void get(); }static class Consumer extends Thread { private Buffer ShareLocation;public Consumer(Buffer shared) {ShareLocation = shared;}public void run() {synchronized (ShareLocation) {try { // while (Producer.i != 0) { // ShareLocation.wait(); // }ShareLocation.get(); System.out.println(Thread.currentThread().getName() + "读出完成");} catch (Exception e) {e.printStackTrace(); }}}}static class Producer extends Thread {private static Buffer ShareLocation; public static int i = 1;public Producer(Buffer shared) { ShareLocation = shared;}public void run() {synchronized (ShareLocation) { try {ShareLocation.set(); i = 0; ShareLocation.notify();} catch (Exception e) {e.printStackTrace(); }}}}static class UnsynchronizedBuffer implements Buffer {public void set() {try {System.err.println(Thread.currentThread().getName() + "写入"); Thread.sleep(3000); System.err.println(Thread.currentThread().getName() + "写入完成");} catch (Exception e) { // TODO: handle exception }}public void get() { try {System.out.println(Thread.currentThread().getName() + "读出"); Thread.sleep(300);} catch (Exception e) { // TODO: handle exception } } }}
虽然输出上像多个线程可以同时读出,但看代码实际上是解锁一次一次的读的,怎么在此基础上实现真正的多个线程同时读?
------解决方案--------------------
- Java code
//给你个现成的例子,jdk里面的import java.util.Map;import java.util.TreeMap;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantReadWriteLock;import javax.xml.crypto.Data;class RWDictionary { private final Map<String, Data> m = new TreeMap<String, Data>(); private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); private final Lock w = rwl.writeLock(); public Data get(String key) { r.lock(); try { return m.get(key); } finally { r.unlock(); } } public String[] allKeys() { r.lock(); try { return m.keySet().toArray(new String[0]); } finally { r.unlock(); } } public Data put(String key, Data value) { w.lock(); try { return m.put(key, value); } finally { w.unlock(); } } public void clear() { w.lock(); try { m.clear(); } finally { w.unlock(); } }}
------解决方案--------------------
- Java code
static String aa="内存共享模块";static final String lock ="锁";static int power = 1;public Object operateAA(String action)throws Exception{ Object o = null; if(-1==power){ throw new Exception("有一线程在进行修改动作"); } if("写".equals(action)){ synchronized(lock){ power = -1; ...... power = 1; } }else{ } return o;}