Java - 带有 wait() 和 notify() 的两个线程
Java - two threads with wait() and notify()
我是 Java 编程新手。我想 运行 两个线程使用 wait() 和 notify()。但是我不能将任务标志用于线程同步、睡眠、屈服或等待(参数)。我写了它,但我不得不使用睡眠。谁能帮我把它改成不睡觉。
这是我的主要class
public class mainClass{
public static void main(String args[]) throws InterruptedException {
final Processor processor = new Processor();
for(int i=0; i<100; i++){
final int z = i;
Thread trainer = new Thread(new Runnable(){
public void run(){
try{
processor.produce(z);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});
Thread sportsman = new Thread(new Runnable(){
public void run(){
try{
processor.consume(z);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});
trainer.start();
sportsman.start();
trainer.join();
sportsman.join();
}
System.out.println("100 Tasks are Finished.");
}
}
这是我的第二个 class。
public class Processor {
public void produce(int n) throws InterruptedException {
synchronized (this){
System.out.println("Trainer making " + (n+1) + " Task..." );
wait();
System.out.println("");
}
}
public void consume(int m) throws InterruptedException {
Thread.sleep(1);
//I want to run the code without using sleep and get same output
synchronized (this){
System.out.println("Sportman doing " + (m+1) + " Task...");
notify();
}
}
}
这是我的输出。
Trainer making 1 Task...
Sportman doing 1 Task...
Trainer making 2 Task...
Sportman doing 2 Task...
.
.
.
Trainer making 99 Task...
Sportman doing 99 Task...
Trainer making 100 Task...
Sportman doing 100 Task...
100 Tasks are Finished.
谢谢。我的英语不好。对不起。
在 mainClass 中你创建了 100 次两个线程,我认为你应该只创建两个线程并且在这两个线程中 运行 循环 100 次。
可能你需要做这样的事情...
- 生产者应该一起创建 100 个任务(一次一个)并在每个任务完成后等待消费者完成。
- 消费者应该等待任务并在完成当前任务后通知生产者,他们等待下一个任务。
所以您的 mainClass 应该看起来像这样,循环应该在 producer() 和 consumer() 方法中。
public class mainClass {
public static void main(String args[]) throws InterruptedException {
final Processor processor = new Processor();
Thread trainer = new Thread(new Runnable() {
public void run() {
try {
processor.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread sportsman = new Thread(new Runnable() {
public void run() {
try {
processor.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
trainer.start();
sportsman.start();
trainer.join();
sportsman.join();
System.out.println("100 Tasks are Finished.");
}
}
处理器可能是这样的...
public class Processor {
private int taskNo = 0; // the number of the current task
// (0 = there is no task, but will be)
// (-1 = there won't be more task)
public void produce() throws InterruptedException {
synchronized (this) {
for (int i = 0; i < 100; i++) {
taskNo = i + 1; // making a task number (i+1)
System.out.println("Trainer making " + taskNo + " Task...");
notify(); // notifies the consumer that the task was made
wait(); // and waiting the consumer to finish... zzzz...
System.out.println("");
}
taskNo = -1; // there will be no more task
notify(); // notify the consumer about it
}
}
public void consume() throws InterruptedException {
synchronized (this) {
do {
if (taskNo == 0) {
wait(); // there is no task to do, waiting... zzzz...
}
if (taskNo != -1) {
System.out.println("Sportman doing " + taskNo + " Task...");
taskNo = 0; // sets the task to done
notify(); // notifies the producer that the task was done
}
} while (taskNo != -1);
}
}
}
通常有一个队列而不是 taskNo 变量,生产者在其中放置任务,消费者从中获取任务。但是在您的情况下,队列一次只能有 1 个任务,因为生产者应该等待消费者来完成。所以你可以使用一个简单的变量(taskNo)来代替队列。
提示:
wait
的正确用法包括等待特定的事情发生。正确的实现是这样的
synchronize (x) {
while (!x.itHasHappened()) {
x.wait(); // for it to happen
}
}
循环是必要的,因为在原始锁上可能会收到虚假通知。
在你的具体例子中,问问自己什么必须等待什么发生。我想你弄错了。 produce(N)
实际上在等待什么,为什么?
我是 Java 编程新手。我想 运行 两个线程使用 wait() 和 notify()。但是我不能将任务标志用于线程同步、睡眠、屈服或等待(参数)。我写了它,但我不得不使用睡眠。谁能帮我把它改成不睡觉。 这是我的主要class
public class mainClass{
public static void main(String args[]) throws InterruptedException {
final Processor processor = new Processor();
for(int i=0; i<100; i++){
final int z = i;
Thread trainer = new Thread(new Runnable(){
public void run(){
try{
processor.produce(z);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});
Thread sportsman = new Thread(new Runnable(){
public void run(){
try{
processor.consume(z);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});
trainer.start();
sportsman.start();
trainer.join();
sportsman.join();
}
System.out.println("100 Tasks are Finished.");
}
}
这是我的第二个 class。
public class Processor {
public void produce(int n) throws InterruptedException {
synchronized (this){
System.out.println("Trainer making " + (n+1) + " Task..." );
wait();
System.out.println("");
}
}
public void consume(int m) throws InterruptedException {
Thread.sleep(1);
//I want to run the code without using sleep and get same output
synchronized (this){
System.out.println("Sportman doing " + (m+1) + " Task...");
notify();
}
}
}
这是我的输出。
Trainer making 1 Task...
Sportman doing 1 Task...
Trainer making 2 Task...
Sportman doing 2 Task...
.
.
.
Trainer making 99 Task...
Sportman doing 99 Task...
Trainer making 100 Task...
Sportman doing 100 Task...
100 Tasks are Finished.
谢谢。我的英语不好。对不起。
在 mainClass 中你创建了 100 次两个线程,我认为你应该只创建两个线程并且在这两个线程中 运行 循环 100 次。
可能你需要做这样的事情...
- 生产者应该一起创建 100 个任务(一次一个)并在每个任务完成后等待消费者完成。
- 消费者应该等待任务并在完成当前任务后通知生产者,他们等待下一个任务。
所以您的 mainClass 应该看起来像这样,循环应该在 producer() 和 consumer() 方法中。
public class mainClass {
public static void main(String args[]) throws InterruptedException {
final Processor processor = new Processor();
Thread trainer = new Thread(new Runnable() {
public void run() {
try {
processor.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread sportsman = new Thread(new Runnable() {
public void run() {
try {
processor.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
trainer.start();
sportsman.start();
trainer.join();
sportsman.join();
System.out.println("100 Tasks are Finished.");
}
}
处理器可能是这样的...
public class Processor {
private int taskNo = 0; // the number of the current task
// (0 = there is no task, but will be)
// (-1 = there won't be more task)
public void produce() throws InterruptedException {
synchronized (this) {
for (int i = 0; i < 100; i++) {
taskNo = i + 1; // making a task number (i+1)
System.out.println("Trainer making " + taskNo + " Task...");
notify(); // notifies the consumer that the task was made
wait(); // and waiting the consumer to finish... zzzz...
System.out.println("");
}
taskNo = -1; // there will be no more task
notify(); // notify the consumer about it
}
}
public void consume() throws InterruptedException {
synchronized (this) {
do {
if (taskNo == 0) {
wait(); // there is no task to do, waiting... zzzz...
}
if (taskNo != -1) {
System.out.println("Sportman doing " + taskNo + " Task...");
taskNo = 0; // sets the task to done
notify(); // notifies the producer that the task was done
}
} while (taskNo != -1);
}
}
}
通常有一个队列而不是 taskNo 变量,生产者在其中放置任务,消费者从中获取任务。但是在您的情况下,队列一次只能有 1 个任务,因为生产者应该等待消费者来完成。所以你可以使用一个简单的变量(taskNo)来代替队列。
提示:
wait
的正确用法包括等待特定的事情发生。正确的实现是这样的synchronize (x) { while (!x.itHasHappened()) { x.wait(); // for it to happen } }
循环是必要的,因为在原始锁上可能会收到虚假通知。
在你的具体例子中,问问自己什么必须等待什么发生。我想你弄错了。
produce(N)
实际上在等待什么,为什么?