Java 为什么读写锁示例是dosen';不行?

Java 为什么读写锁示例是dosen';不行?,java,multithreading,concurrency,locking,Java,Multithreading,Concurrency,Locking,LinkedList尝试轮询数据时引发异常。但我认为我正确地使用了读/写锁的概念。那个代码有什么问题 package sample; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Co

LinkedList
尝试轮询数据时引发异常。但我认为我正确地使用了读/写锁的概念。那个代码有什么问题

package sample;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class PingPong extends Thread {
    boolean read = false;
    Queue<String> queue;
    static ReadWriteLock lock = new ReentrantReadWriteLock();
    final static Lock readLock = lock.readLock();
    final static Lock writeLock = lock.writeLock();
    boolean stop;

    public PingPong(boolean read, Queue<String> queue) {
        this.read = read;
        this.queue = queue;
    }

    int count = 0;

    @Override
    public String toString() {
        return "PingPong{" +
                "read=" + read +
                ", count=" + count +
                '}';
    }

    @Override
    public void run() {
        if (read) {
            while (!stop) {

                readLock.lock();
//                synchronized (queue) {
                try {

                    String string = queue.poll();
                    if (string != null) {
                        count++;
                    }
                } finally {
                    readLock.unlock();
                }


//                }
                inform();
            }
        } else {
            while (!stop) {

                writeLock.lock();
//                synchronized (queue) {
                try {
                    if (queue.add("some str" + count)) {
                        count++;
                    }
                } finally {
                    writeLock.unlock();
                }

//                }

                inform();
            }

        }


    }

    private void inform() {
//        Thread.yield();
//        synchronized (queue) {
//            queue.notify();
//            try {
//                queue.wait(1);
//            } catch (InterruptedException e) {
//                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
//            }
//        }
    }

    public static void main(String[] args) throws InterruptedException {
        Queue<String> queue = new LinkedList();
//        queue = new ArrayBlockingQueue<String>(100);
//        queue = new ConcurrentLinkedQueue<String>();
        List<PingPong> pongs = new ArrayList<PingPong>();
        for (int i = 0; i < 10; ++i) {
            PingPong pingPong = new PingPong(i % 2 == 0, queue);
            pingPong.start();
            pongs.add(pingPong);
        }
        Thread.sleep(1000);
        int sum = 0;
        int read = 0;
        int write = 0;
        for (PingPong pp : pongs) {
            pp.stop = true;
            pp.join();
        }
        for (PingPong pp : pongs) {
            System.out.println(pp);
            sum += pp.count;
            if (pp.read) read += pp.count;
            else write += pp.count;
        }
        System.out.println(sum);
        System.out.println("write = " + write);
        System.out.println("read = " + read);
        System.out.println("queue.size() = " + queue.size());
        System.out.println("balance (must be zero) = " + (write - read - queue.size()));

    }
}
包装样品;
导入java.util.ArrayList;
导入java.util.LinkedList;
导入java.util.List;
导入java.util.Queue;
导入java.util.concurrent.ArrayBlockingQueue;
导入java.util.concurrent.ConcurrentLinkedQueue;
导入java.util.concurrent.locks.Lock;
导入java.util.concurrent.locks.ReadWriteLock;
导入java.util.concurrent.locks.ReentrantReadWriteLock;
公共类乒乓球扩展线程{
布尔读取=假;
排队;
静态读写锁=新的ReentrantReadWriteLock();
最终静态锁readLock=Lock.readLock();
最终静态锁writeLock=Lock.writeLock();
布尔停止;
公共乒乓球(布尔读取、队列){
this.read=read;
this.queue=队列;
}
整数计数=0;
@凌驾
公共字符串toString(){
返回“乒乓球{”+
“读取=”+读取+
“,count=“+count+
'}';
}
@凌驾
公开募捐{
如果(读){
当(!停止){
readLock.lock();
//已同步(队列){
试一试{
String字符串=queue.poll();
if(字符串!=null){
计数++;
}
}最后{
readLock.unlock();
}
//                }
通知();
}
}否则{
当(!停止){
writeLock.lock();
//已同步(队列){
试一试{
if(queue.add(“some str”+count)){
计数++;
}
}最后{
writeLock.unlock();
}
//                }
通知();
}
}
}
私人通知{
//螺纹屈服强度();
//已同步(队列){
//queue.notify();
//试一试{
//排队等候(1);
//}catch(InterruptedException e){
//e.printStackTrace();//要更改catch语句的主体,请使用文件|设置|文件模板。
//            }
//        }
}
公共静态void main(字符串[]args)引发InterruptedException{
Queue Queue=new LinkedList();
//队列=新的ArrayBlockingQueue(100);
//队列=新的ConcurrentLinkedQueue();
List pongs=new ArrayList();
对于(int i=0;i<10;++i){
乒乓球乒乓球=新乒乓球(i%2==0,队列);
乒乓球;
添加(乒乓球);
}
睡眠(1000);
整数和=0;
int read=0;
int write=0;
用于(乒乓球pp:pongs){
pp.stop=true;
pp.join();
}
用于(乒乓球pp:pongs){
系统输出打印项次(pp);
总和+=pp计数;
如果(pp.read)read+=pp.count;
else write+=pp.count;
}
系统输出打印项数(总和);
System.out.println(“write=“+write”);
System.out.println(“read=“+read”);
System.out.println(“queue.size()=”+queue.size());
System.out.println(“余额(必须为零)=”+(write-read-queue.size());
}
}

这是因为此调用变异了
队列
集合:

String string = queue.poll();
从JavaDoc:

检索并删除此队列的头,如果此队列为空,则返回null

读锁用于多线程可以安全读取的情况,而写操作必须以独占方式执行(没有其他读写操作)。由于您使用读锁来轮询队列(写操作!),因此实际上允许多个线程同时修改非线程安全的
LinkedList


在这种情况下,读写锁不是正确的同步机制。

在发布问题之前,请粘贴异常并清理代码。非常感谢。