我在这段代码中有一个死锁,但我不明白为什么。
有3个班和主班。
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class TestThread {
private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
private static final String message = "a";
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new WriterA(lock, message), "Writer A");
Thread thread2 = new Thread(new WriterB(lock, message), "Writer B");
Thread thread3 = new Thread(new Reader(lock), "Reader");
thread1.start();
thread2.start();
thread3.start();
thread1.join();
thread2.join();
thread3.join();
}
}
这是一个阅读器类:
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Reader implements Runnable {
private final ReentrantReadWriteLock lock;
public Reader(ReentrantReadWriteLock lock) {
this.lock = lock;
}
@Override
public void run() {
if (lock.isWriteLocked()) {
System.out.println("Write lock present.");
}
lock.readLock().lock();
System.out.println("Readlock lock");
try {
Long duration = (long) (Math.random() * 10000);
System.out.println(Thread.currentThread().getName() + " taken " + (duration/1000) + " seconds.");
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("Unlock readlock");
lock.readLock().unlock();
}
}
}
这是作家B:
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class WriterB implements Runnable {
private final ReentrantReadWriteLock lock;
private String message;
public WriterB(ReentrantReadWriteLock lock, String message) {
this.lock = lock;
this.message = message;
}
@Override
public void run() {
while(true) {
if (lock.writeLock().tryLock()) {
lock.writeLock().lock();
System.out.println(Thread.currentThread().getName() + ": Locking now");
try {
long duration = (long) (Math.random() * 10000);
System.out.println(Thread.currentThread().getName() + " taken " + (duration/1000) + " seconds.");
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
message = message.concat("b");
System.out.println(Thread.currentThread().getName() + ": Unlock now");
lock.writeLock().unlock();
}
break;
} else {
System.out.println(Thread.currentThread().getName() + ": Write lock is present. Waiting 1000 ms.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
这是作家A:
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class WriterA implements Runnable {
private final ReentrantReadWriteLock lock;
private String message;
public WriterA(ReentrantReadWriteLock lock, String message) {
this.lock = lock;
this.message = message;
}
@Override
public void run() {
lock.writeLock().lock();
System.out.println(Thread.currentThread().getName() + ": Locking now");
try {
Long duration = (long) (Math.random() * 10000);
System.out.println(Thread.currentThread().getName() + " taken " + (duration/1000) + " seconds.");
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
message = message.concat("a");
System.out.println(Thread.currentThread().getName() + ": Unlock now");
lock.writeLock().unlock();
}
}
}
当我运行主类时,有时所有类都在那里工作,但是当 Writer B 启动时它陷入死锁。
坏情况控制台输出:
Writer B: Locking now
Writer B taken 4 seconds.
Writer B: Unlock now
好案例控制台输出:
Writer A: Locking now
Writer B: Write lock is present. Waiting 1000 ms.
Writer A taken 5 seconds.
Writer B: Write lock is present. Waiting 1000 ms.
Writer B: Write lock is present. Waiting 1000 ms.
Writer B: Write lock is present. Waiting 1000 ms.
Writer B: Write lock is present. Waiting 1000 ms.
Writer B: Write lock is present. Waiting 1000 ms.
Writer A: Unlock now
Readlock lock
Reader taken 3 seconds.
Writer B: Write lock is present. Waiting 1000 ms.
Writer B: Write lock is present. Waiting 1000 ms.
Writer B: Write lock is present. Waiting 1000 ms.
Writer B: Write lock is present. Waiting 1000 ms.
Unlock readlock
Writer B: Locking now
Writer B taken 7 seconds.
Writer B: Unlock now