我想在两个线程之间建立这样的通信:第一个线程(Sender)向第二个线程(Receiver)发送一个整数,Receiver显示这个整数的平方。下面是我的代码:Carre.java(main) :
public class Carre {
static Boolean msgArrived = Boolean.FALSE ;
static int n ;
public static void main(String[] args) {
Thread sender = new Thread(new Sender()) ;
Thread receiver = new Thread(new Receiver()) ;
sender.start() ;
receiver.start() ;
}
public int getN() {
return n;
}
}Sender.java :
import java.util.Random;
public class Sender implements Runnable {
@Override
public void run() {
while(Carre.msgArrived == Boolean.TRUE) {
try {
wait() ;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i = 0; i < 10; i ++) {
Random ran = new Random() ;
Carre.n = ran.nextInt(100) ;
Carre.msgArrived = Boolean.TRUE ;
notifyAll() ;
}
}
}Receiver.java
公共类接收器实现Runnable {
@Override
public void run() {
while(Carre.msgArrived == Boolean.FALSE) {
try {
wait() ;
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Carre.n * Carre.n) ;
Carre.msgArrived = Boolean.TRUE ;
notifyAll() ;
}
}&当我试图执行我的代码时,我会收到以下错误消息:
线程"Thread-1“java.lang.IllegalMonitorStateException中的异常
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at Receiver.run(Receiver.java:12)
at java.lang.Thread.run(Thread.java:636)线程" thread -0“java.lang.IllegalMonitorStateException中的异常
at java.lang.Object.notifyAll(Native Method)
at Sender.run(Sender.java:19)
at java.lang.Thread.run(Thread.java:636)发布于 2012-01-22 11:57:45
在我看来,最好不要直接使用线程,因为它们是级别太低的并发实体,因此更难使用。通过java.util.concurrent包工具,您应该能够更容易地设计出生产者/消费者场景。
你可以在这里看看:使用队列的生产者/使用者线程
发布于 2012-01-22 11:47:52
这里的问题还不清楚,但我建议您尝试以下几种方法:
//Carre.java
public class Carre {
//package level access
static List<Integer> queue = new ArrayList<Integer>();
public static void main(String[] args) {
Thread sender = new Sender();
Thread receiver = new Receiver();
sender.start();
receiver.start();
}
//package-level access
static boolean available() {
synchronized(queue) {
return ! queue.isEmpty();
}
}
static int getNext() {
synchronized(queue) {
return queue.remove(0);
}
}
static void enqueue(int next) {
synchronized(queue) {
queue.add(next);
}
}
}
//Sender.java
public class Sender extends Thread {
private boolean stop = false;
public void stopRunning() {
stop = true;
}
@Override
public void run() {
while (! stop) {
for(int i = 0; i < 10; i ++) {
Random ran = new Random() ;
Carre.enqueue(ran.nextInt(100));
}
try {
synchronized(Carre.queue) {
Carre.queue.notify();
Carre.queue.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//Receiver.java
public class Receiver extends Thread {
private boolean stop = false;
public void stopRunning() {
stop = true;
}
@Override
public void run() {
while(! stop) {
while (Carre.available()) {
int next = Carre.getNext();
System.out.println(next * next) ;
}
try {
synchronized(Carre.queue) {
Carre.queue.notify();
Carre.queue.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}当然,由于类之间的紧密耦合,这并不是理想的编码风格,但它确实演示了如何在线程之间共享数据的基本知识,从而使生产者和使用者线程保持同步。
请注意,如果您正在获得一个java.lang.IllegalMonitorStateException,这是因为您正在对一个对象调用wait()或notify(),而您在第一个对象上没有进行同步。您可以通过执行synchronized(object) { //code... }对对象进行同步。
发布于 2012-01-22 18:49:10
此错误是因为您只能对当前线程为wait()的对象调用synchronized和synchronized。文档对此非常清楚。
你应该这样做:
public static void main(String[] args) {
Object lock = new Object();
Thread sender = new Thread(new Sender(lock)) ;
Thread receiver = new Thread(new Receiver(lock)) ;
sender.start() ;
receiver.start() ;
}
class Sender implements Runnable {
private final Object lock;
Sender(Object lock) { this.lock = lock; }
@Override
public void run() {
synchronized (lock) {
while(Carre.msgArrived == Boolean.TRUE) {
try {
lock.wait() ;
} catch (InterruptedException ex) {
/* Interruption is a request to abort operation ASAP. */
ex.printStackTrace();
Thread.currentThread().interrupt();
return;
}
}
}
...
}对Receiver的锁执行类似的操作,在synchronized(lock)块中调用lock.notify()。
与将lock对象传递给发送方和接收方以及编写您自己的同步逻辑相比,更好的方法是使用并发队列,如SynchronousQueue。
https://stackoverflow.com/questions/8960704
复制相似问题