import java.util.*;public class ReadersWritersSingleClassSolution implements Runnable{ private static final Object lock = new Object();  private int indexObject = 0;
private int readerIndex = 0;

@Override
public void run() {
while(true) {
toRead();
try {
toWrite();
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public synchronized void toRead() {
ReaderList.addReader(new Reader(Thread.currentThread().getClass().toString(),readerIndex++));
ReaderList.pollReader();
System.out.println(Thread.currentThread().getName() + "Read indexObject = " + indexObject);
}

public synchronized void toWrite() throws InterruptedException {
synchronized (lock) {
indexObject++;
System.out.println(Thread.currentThread().getName() + "Write indexObject = " + indexObject);
}
}

public static void main(String[] args) {
new Thread(new ReadersWritersSingleClassSolution()).start();
new Thread(new ReadersWritersSingleClassSolution()).start();
new Thread(new ReadersWritersSingleClassSolution()).start();
new Thread(new ReadersWritersSingleClassSolution()).start();
new Thread(new ReadersWritersSingleClassSolution()).start();
} static class ReaderList {
static Queue<Reader> readQueue = new LinkedList<Reader>(); public static void addReader(Reader r) {
synchronized (ReaderList.class) {
readQueue.offer(r);
}
} public static synchronized void pollReader() {
synchronized (ReaderList.class) {
readQueue.poll();
}
} } class Reader {
private String name = null;
private int index = 0; Reader(String str, int index) {
this.name = str;
this.index = index;
} public int getIndex() {
return this.index;
} public String getName() {
return name;
} public String toString() {
return Thread.currentThread().getName() + " Reader " + name;
}
} }
按照老紫老师的讲法  已经配上了  private static final Object lock = new Object();  这个锁我希望实现的是1. 任何时候都可以读toRead  但是需要进入一个队列  再读
2. 需要同步所有线程的toWrite方法  也就是说toWrite在一个时候只能有一个线程使用现在的问题是1. toWrite方法没有同步  我想知道为什么?

解决方案 »

  1.   

    1. toWrite方法没有同步  我想知道为什么?
    toWrite方法肯定是同步的,不过你这代码里同步毫无意义,因为没有共享的资源
    改成这样吧private static int indexObject = 0;
    至少添加一个能共享的资源,才能观察出来同步的效果
      

  2.   

    你已经用了synchronized关键字加锁了:public synchronized void toWrite() throws InterruptedException {
            synchronized (lock) {
              //...
            }
    }
      

  3.   


    我希望可以一次只有一个线程访问toWrite方法改成静态资源是可以看得出效果  但是5个线程还是不能做到在同一个时间只有一个线程去访问toWrite方法
      

  4.   

     synchronized (lock){}
    里的内容并发下是同步的,应为你是在一个static对象上加的监视器,所有的ReadersWritersSingleClassSolution实例共享一个lock对象,
    所以这个lock对象监视所有在此对象加锁的线程
      

  5.   

    都说了是同步的了啊
    如果楼主是想要正个toWrite同步的话,而不是用临界区去同步,那么把toWrite方法改为
    public static synchronized void toWrite() throws InterruptedException {
                indexObject++;
                System.out.println(Thread.currentThread().getName() + "Write indexObject = " + indexObject);
        }
    这个样子吧,此时toWrite方法中JVM在ReadersWritersSingleClassSolution的class对象上加监视器
      

  6.   

    楼主想的是生产者-消费者那种同步吧,如果是这样,你的结构得做调整,toWork方法不应放在ReadersWritersSingleClassSolution类里,还是应该在一个管理你的这些Runnable接口实例的包装类里,在此做同步。没办法,正看球赛,没空给你写重复的代码,你自己找书看看吧。
      

  7.   


    //一般来说 读写问题的解决方法是用synchronized 加上wait();方法
    //也就是说  除了你用的synchronized代码快或者方法外  
    //  还需要另一个flag去标记 让其他的线程等待  直到一个同步方法执行完了  然后notify()掉import java.util.*;public class ReadersWritersSingleClassSolution implements Runnable { private final Object lock = new Object();
    private static volatile boolean writeLock = true; private static int indexObject = 0;
    private int readerIndex = 0; @Override
    public void run() {
    while (true) {
    toRead();
    try {
    toWrite();
    Thread.sleep(1500);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    } public synchronized void toRead() {
    ReaderList.addReader(new Reader(Thread.currentThread().getClass()
    .toString(), readerIndex++));
    ReaderList.pollReader();
    System.out.println(Thread.currentThread().getName()
    + "Read indexObject = " + indexObject);
    } public synchronized void toWrite() throws InterruptedException {
    synchronized (lock) {
    while (writeLock == false) {
    wait();
    }
    writeLock = false;
    indexObject++;
    System.out.println(Thread.currentThread().getName()
    + "Write indexObject = " + indexObject);
    Thread.sleep(3000);
    writeLock = true;
    notify(); }
    } public static void main(String[] args) {
    new Thread(new ReadersWritersSingleClassSolution()).start();
    new Thread(new ReadersWritersSingleClassSolution()).start();
    new Thread(new ReadersWritersSingleClassSolution()).start();
    new Thread(new ReadersWritersSingleClassSolution()).start();
    new Thread(new ReadersWritersSingleClassSolution()).start();
    } static class ReaderList {
    static Queue<Reader> readQueue = new LinkedList<Reader>(); public static void addReader(Reader r) {
    synchronized (ReaderList.class) {
    readQueue.offer(r);
    }
    } public static synchronized void pollReader() {
    synchronized (ReaderList.class) {
    readQueue.poll();
    }
    } } class Reader {
    private String name = null;
    private int index = 0; Reader(String str, int index) {
    this.name = str;
    this.index = index;
    } public int getIndex() {
    return this.index;
    } public String getName() {
    return name;
    } public String toString() {
    return Thread.currentThread().getName() + " Reader " + name;
    }
    }}
      

  8.   

    线程同步的前提条件是对象实体只有一个,不同的线程对于同一个对象进行访问时,对于
    用synchronized修饰的方法或代码段同一时间只允许一个线程访问,而你却对于多个实体进行同步
            new Thread(new ReadersWritersSingleClassSolution()).start();
            new Thread(new ReadersWritersSingleClassSolution()).start();
            new Thread(new ReadersWritersSingleClassSolution()).start();
            new Thread(new ReadersWritersSingleClassSolution()).start();
            new Thread(new ReadersWritersSingleClassSolution()).start();