Reader 作者使用 Java 线程时遇到问题
Reader writers problem using Java Threads
我一直在尝试在 Java 中解决 reader 编写器问题。但是当Thread.Sleep(5000)执行时,当前线程进程并没有中断。
比如第一个reader进入数据库,进程休眠5秒,我想让第二个reader进入数据库。但是在我的代码中,第二个 reader 仅在第一个 reader 醒来并离开数据库后才进入数据库
如何达到我想要的结果?
import java.util.Scanner;
class CriticalSec {
static boolean mutex = true;
static boolean db = true;
static int readerCount = 0;
static Writer arrWriter = new Writer();
static Reader1 r1= new Reader1();
static Reader2 r2= new Reader2();
public void readerEnter() throws InterruptedException {
if (readerCount==0){
r1.enter();
}else{
r1.enter();
}
if (mutex) {
mutex = false;
}
readerCount += 1;
if (readerCount == 1) {
if (db) {
db = false;
} else {
System.out.println("\nReader cannot enter database.\n");
System.out.println("Waiting for writer to exit....");
wait();
}
}
if (!mutex) {
mutex = true;
Thread.sleep(5000);
if (readerCount==1){
r1.exit();
}else{
r2.exit();
}
}
}
public void WriterEnter() throws InterruptedException {
arrWriter.enter();
if (db) {
db = false;
Thread.sleep(5000);
arrWriter.exit();
notify();
} else {
System.out.println("Writer cannot enter database.");
System.out.println("Waiting for writer/reader to exit....");
wait();
}
}
}
class Reader1 extends Thread {
public void run() {
System.out.println("New reader created.");
}
public void enter() throws InterruptedException {
System.out.println("\nReader 1 has entered in the database...\n");
}
public void exit() {
if (CriticalSec.mutex) {
CriticalSec.mutex = false;
}
CriticalSec.readerCount -= 1;
if (CriticalSec.readerCount == 0) {
CriticalSec.db = true;
}
CriticalSec.mutex = true;
System.out.println("The reader 1 has now left");
}
}
class Reader2 extends Thread {
public void run() {
System.out.println("New reader created.");
}
public void enter() throws InterruptedException {
System.out.println("\nReader 2 has entered in the database...\n");
}
public void exit() {
if (CriticalSec.mutex) {
CriticalSec.mutex = false;
}
CriticalSec.readerCount -= 1;
if (CriticalSec.readerCount == 0) {
CriticalSec.db = true;
}
CriticalSec.mutex = true;
System.out.println("The reader 1 has now left");
}
}
class Writer extends Thread {
public void run() {
System.out.println("New Writer created.");
}
public void enter() throws InterruptedException {
System.out.println("Writer has entered in the database.");
}
public void exit() {
CriticalSec.db = false;
System.out.println("Writer has left the database.");
}
}
public class RWProblem {
public static void main(String[] args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
CriticalSec c = new CriticalSec();
c.readerEnter();
c.readerEnter();
c.WriterEnter();
}
}
我刚开始学习Java,如果我的问题含糊不清,我很抱歉。我很乐意提供更多详细信息。
编辑:
在复习了一些重要概念并进行了大量练习之后,我想出了一个解决方案。有人可以看看它并告诉我它是否合适吗?我该如何改进它?
class RW {
boolean dbOccupied = false;
int readerCount = 0;
boolean writer=false;
public void readerEnter() throws InterruptedException {
while (true) {
synchronized (this) {
while (dbOccupied && readerCount == 0) {
System.out.println("Reader cannot read... Database Occupied");
wait();
}
readerCount++;
dbOccupied = true;
System.out.println("Reader " + readerCount + " is reading...");
// Thread.sleep(1000);
}
}
}
public void readerExit() throws InterruptedException {
while (true) {
synchronized (this) {
while (readerCount != 0) {
System.out.println("Reader " + readerCount + " is now exiting...");
readerCount--;
}
dbOccupied = false;
notifyAll();
// Thread.sleep(1000);
}
}
}
public void writerEnter() throws InterruptedException {
while (true) {
synchronized (this) {
while (dbOccupied){
System.out.println("New writer cannot write... Database Occupied");
wait();
}
dbOccupied = true;
writer=true;
System.out.println("Writer is now writing.....");
// Thread.sleep(1000);
}
}
}
public void writerExit() throws InterruptedException {
while (true) {
synchronized (this) {
if (writer) {
System.out.println("Writer leaving database...");
writer=false;
dbOccupied = false;
notifyAll();
// Thread.sleep(1000);
}
}
}
}
}
public class RW3 {
public static void main(String[] args) throws InterruptedException {
final RW rw= new RW();
Thread t1= new Thread(new Runnable() {
@Override
public void run() {
try {
rw.readerEnter();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2=new Thread(new Runnable() {
@Override
public void run() {
try {
rw.readerExit();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t3= new Thread(new Runnable() {
@Override
public void run() {
try {
rw.writerEnter();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t4= new Thread(new Runnable() {
@Override
public void run() {
try {
rw.writerExit();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// t1.setPriority(2);
// t3.setPriority(10);
t1.start();
t2.start();
t3.start();
t4.start();
t1.join();
t3.join();
t2.join();
t4.join();
}
}
这是我第一次使用 Whosebug 提出问题,我对回答感到震惊!!!!!!我非常喜欢这个社区
您从主线程调用 readEnter
方法,它使主线程进入睡眠状态,因此被阻塞。为了将工作交给 reader 线程本身,您需要在主线程中组织所有内容,然后通过主线程触发 reader 线程。 您只能从 reader 个线程 中调用 readEnter
方法。我没有实施作家,我们鼓励您这样做。不能保证线程启动的顺序,因为它取决于调度。查看示例代码:
class CriticalSec {
private int readerCount = 0;
public boolean readerEnter() throws InterruptedException {
if(readerCount == 0) {
readerCount++;
Thread.sleep(5000);
return true;
}
else if(readerCount == 1) {
readerCount++;
Thread.sleep(5000);
readerCount = 0; // rewind to zero
return true;
}
else {
System.out.println("Both reader threads are busy, "+Thread.currentThread().getName()+" will not be executed");
return false;
}
}
}
class Reader implements Runnable {
private final CriticalSec cs;
public Reader(CriticalSec criticalSec) {
cs = criticalSec;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" goes for reading...");
try {
String state = cs.readerEnter() ? " done reading" : " failed reading!";
System.out.println(Thread.currentThread().getName()+state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class RWProblem {
public static void main(String[] args) {
CriticalSec c = new CriticalSec();
Reader r1 = new Reader(c);
Reader r2 = new Reader(c);
Reader r3 = new Reader(c);
new Thread(r1, "Reader 1").start();
new Thread(r2, "Reader 2").start();
new Thread(r3, "Reader 3").start();
}
}
输出是运行之一:
Reader 3 goes for reading...
Reader 1 goes for reading...
Reader 2 goes for reading...
Both reader threads are busy, Reader 1 will not be executed
Reader 1 failed reading!
Reader 3 done reading
Reader 2 done reading
Process finished with exit code 0
我一直在尝试在 Java 中解决 reader 编写器问题。但是当Thread.Sleep(5000)执行时,当前线程进程并没有中断。
比如第一个reader进入数据库,进程休眠5秒,我想让第二个reader进入数据库。但是在我的代码中,第二个 reader 仅在第一个 reader 醒来并离开数据库后才进入数据库
如何达到我想要的结果?
import java.util.Scanner;
class CriticalSec {
static boolean mutex = true;
static boolean db = true;
static int readerCount = 0;
static Writer arrWriter = new Writer();
static Reader1 r1= new Reader1();
static Reader2 r2= new Reader2();
public void readerEnter() throws InterruptedException {
if (readerCount==0){
r1.enter();
}else{
r1.enter();
}
if (mutex) {
mutex = false;
}
readerCount += 1;
if (readerCount == 1) {
if (db) {
db = false;
} else {
System.out.println("\nReader cannot enter database.\n");
System.out.println("Waiting for writer to exit....");
wait();
}
}
if (!mutex) {
mutex = true;
Thread.sleep(5000);
if (readerCount==1){
r1.exit();
}else{
r2.exit();
}
}
}
public void WriterEnter() throws InterruptedException {
arrWriter.enter();
if (db) {
db = false;
Thread.sleep(5000);
arrWriter.exit();
notify();
} else {
System.out.println("Writer cannot enter database.");
System.out.println("Waiting for writer/reader to exit....");
wait();
}
}
}
class Reader1 extends Thread {
public void run() {
System.out.println("New reader created.");
}
public void enter() throws InterruptedException {
System.out.println("\nReader 1 has entered in the database...\n");
}
public void exit() {
if (CriticalSec.mutex) {
CriticalSec.mutex = false;
}
CriticalSec.readerCount -= 1;
if (CriticalSec.readerCount == 0) {
CriticalSec.db = true;
}
CriticalSec.mutex = true;
System.out.println("The reader 1 has now left");
}
}
class Reader2 extends Thread {
public void run() {
System.out.println("New reader created.");
}
public void enter() throws InterruptedException {
System.out.println("\nReader 2 has entered in the database...\n");
}
public void exit() {
if (CriticalSec.mutex) {
CriticalSec.mutex = false;
}
CriticalSec.readerCount -= 1;
if (CriticalSec.readerCount == 0) {
CriticalSec.db = true;
}
CriticalSec.mutex = true;
System.out.println("The reader 1 has now left");
}
}
class Writer extends Thread {
public void run() {
System.out.println("New Writer created.");
}
public void enter() throws InterruptedException {
System.out.println("Writer has entered in the database.");
}
public void exit() {
CriticalSec.db = false;
System.out.println("Writer has left the database.");
}
}
public class RWProblem {
public static void main(String[] args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
CriticalSec c = new CriticalSec();
c.readerEnter();
c.readerEnter();
c.WriterEnter();
}
}
我刚开始学习Java,如果我的问题含糊不清,我很抱歉。我很乐意提供更多详细信息。
编辑:
在复习了一些重要概念并进行了大量练习之后,我想出了一个解决方案。有人可以看看它并告诉我它是否合适吗?我该如何改进它?
class RW {
boolean dbOccupied = false;
int readerCount = 0;
boolean writer=false;
public void readerEnter() throws InterruptedException {
while (true) {
synchronized (this) {
while (dbOccupied && readerCount == 0) {
System.out.println("Reader cannot read... Database Occupied");
wait();
}
readerCount++;
dbOccupied = true;
System.out.println("Reader " + readerCount + " is reading...");
// Thread.sleep(1000);
}
}
}
public void readerExit() throws InterruptedException {
while (true) {
synchronized (this) {
while (readerCount != 0) {
System.out.println("Reader " + readerCount + " is now exiting...");
readerCount--;
}
dbOccupied = false;
notifyAll();
// Thread.sleep(1000);
}
}
}
public void writerEnter() throws InterruptedException {
while (true) {
synchronized (this) {
while (dbOccupied){
System.out.println("New writer cannot write... Database Occupied");
wait();
}
dbOccupied = true;
writer=true;
System.out.println("Writer is now writing.....");
// Thread.sleep(1000);
}
}
}
public void writerExit() throws InterruptedException {
while (true) {
synchronized (this) {
if (writer) {
System.out.println("Writer leaving database...");
writer=false;
dbOccupied = false;
notifyAll();
// Thread.sleep(1000);
}
}
}
}
}
public class RW3 {
public static void main(String[] args) throws InterruptedException {
final RW rw= new RW();
Thread t1= new Thread(new Runnable() {
@Override
public void run() {
try {
rw.readerEnter();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2=new Thread(new Runnable() {
@Override
public void run() {
try {
rw.readerExit();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t3= new Thread(new Runnable() {
@Override
public void run() {
try {
rw.writerEnter();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t4= new Thread(new Runnable() {
@Override
public void run() {
try {
rw.writerExit();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// t1.setPriority(2);
// t3.setPriority(10);
t1.start();
t2.start();
t3.start();
t4.start();
t1.join();
t3.join();
t2.join();
t4.join();
}
}
这是我第一次使用 Whosebug 提出问题,我对回答感到震惊!!!!!!我非常喜欢这个社区
您从主线程调用 readEnter
方法,它使主线程进入睡眠状态,因此被阻塞。为了将工作交给 reader 线程本身,您需要在主线程中组织所有内容,然后通过主线程触发 reader 线程。 您只能从 reader 个线程 中调用 readEnter
方法。我没有实施作家,我们鼓励您这样做。不能保证线程启动的顺序,因为它取决于调度。查看示例代码:
class CriticalSec {
private int readerCount = 0;
public boolean readerEnter() throws InterruptedException {
if(readerCount == 0) {
readerCount++;
Thread.sleep(5000);
return true;
}
else if(readerCount == 1) {
readerCount++;
Thread.sleep(5000);
readerCount = 0; // rewind to zero
return true;
}
else {
System.out.println("Both reader threads are busy, "+Thread.currentThread().getName()+" will not be executed");
return false;
}
}
}
class Reader implements Runnable {
private final CriticalSec cs;
public Reader(CriticalSec criticalSec) {
cs = criticalSec;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" goes for reading...");
try {
String state = cs.readerEnter() ? " done reading" : " failed reading!";
System.out.println(Thread.currentThread().getName()+state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class RWProblem {
public static void main(String[] args) {
CriticalSec c = new CriticalSec();
Reader r1 = new Reader(c);
Reader r2 = new Reader(c);
Reader r3 = new Reader(c);
new Thread(r1, "Reader 1").start();
new Thread(r2, "Reader 2").start();
new Thread(r3, "Reader 3").start();
}
}
输出是运行之一:
Reader 3 goes for reading...
Reader 1 goes for reading...
Reader 2 goes for reading...
Both reader threads are busy, Reader 1 will not be executed
Reader 1 failed reading!
Reader 3 done reading
Reader 2 done reading
Process finished with exit code 0