要求: 
1.        线程x在读取共享内存时必须确保读取的内容可靠, 因此在读取过程中, Shared Memory存储的内容不能被其他线程改变. 
2.        所有线程(无论读或写)无序且并发执行. 
3.        线程x写内存Shared Memory时, 为保证其他线程读取的内容真实可靠, 在写操作未完成时, 不允许任何线程读取. 
4.        当线程x读取Shared Memory时, 其他线程也可以读取. 
5.        当线程x 写内存Shared Memory时, 未保证数据一致性, 其他线程不允许写. 
我自己写的代码如下:
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  }  } }}虽然输出上像多个线程可以同时读出,但看代码实际上是解锁一次一次的读的,怎么在此基础上实现真正的多个线程同时读?

解决方案 »

  1.   


    //给你个现成的例子,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();
            }
        }
    }
      

  2.   

    ReentrantReadWriteLocks can be used to improve concurrency in some uses of some kinds of Collections. This is typically worthwhile only when the collections are expected to be large, accessed by more reader threads than writer threads, and entail operations with overhead that outweighs synchronization overhead. For example, here is a class using a TreeMap that is expected to be large and concurrently accessed. 
      

  3.   

    谢谢 用lock解决了,但3楼说的仅仅只是读,如果不锁,就没法实现写的时候不能读啊。其实我挺想知道用synchronized怎么解决。
      

  4.   

    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;
      

  5.   

    用synchronized
    因为读写是互斥的
    貌似没办法区别读写线程,无法对读写线程区别对待,不知道有没有方法,我想要实现至少要像readWriteLock那样能区别读写线程
    比如当前虽然是读线程占据了锁,但是后续读线程欲进入读同步快,也会被拒之门外