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
在这种情况下,读写锁不是正确的同步机制。在发布问题之前,请粘贴异常并清理代码。非常感谢。