Java 线程使用while循环运行

Java 线程使用while循环运行,java,multithreading,Java,Multithreading,我有一个简单的多线程程序,如下所示: 我有T1、T2、T3…Tn线程,它们都是并行运行的。 每个线程都有一个对象队列,我想从中添加/删除项目。 在每一次添加中,我都希望将其打印到屏幕上 public void run() { while(!queue.isEmpty()) { Object obj = queue.poll(); System.out.println(obj.toString()); } } 此外,我只使用: vo

我有一个简单的多线程程序,如下所示:

我有T1、T2、T3…Tn线程,它们都是并行运行的。 每个线程都有一个对象队列,我想从中添加/删除项目。 在每一次添加中,我都希望将其打印到屏幕上

public void run() {
    while(!queue.isEmpty()) {
            Object obj = queue.poll();
            System.out.println(obj.toString());
    }
}
此外,我只使用:

void addObj(Object obj) {
    this.queue.add(obj);
}
在同一类线程中

我在不同的时间在整个程序中使用
addObj

问题当我向队列中添加对象时,
run
似乎根本不在乎。 在某些情况下,它确实打印了新对象,但在许多情况下它没有打印,并且它仍然认为队列是空的

如何确保线程知道正在添加此项? 我应该使用回调吗? 对于这些任务,正确的方法是什么

  • 我还注意到,当我使用Thred.sleep()时,它会有所帮助,但我想它看起来很难看
更新:每个线程都应该有自己的线程。我在一个单独的“线程管理器”中创建线程,它一个接一个地启动线程。 每个线程都有自己的私有队列,应该动态填充。 可以在线程启动之前和之后的任何给定时间将项目添加/删除到队列。

如果队列为空,您的
run()
方法将立即完成。如果希望线程在队列为空的情况下工作,请使用以下方法:

public void run() {
    while(true) {
        if (!queue.isEmpty()) {
            Object obj = queue.poll();
            System.out.println(obj.toString());
        }
    }
}
如果队列为空,您的
run()
方法将立即完成。如果希望线程在队列为空的情况下工作,请使用以下方法:

public void run() {
    while(true) {
        if (!queue.isEmpty()) {
            Object obj = queue.poll();
            System.out.println(obj.toString());
        }
    }
}

这里有一个更漂亮的解决方案。避免轮询;)

下面是要添加的代码:

void addObj(Object obj) {
    this.queue.add(obj);
    this.queue.notify();
}

这里有一个更漂亮的解决方案。避免轮询;)

下面是要添加的代码:

void addObj(Object obj) {
    this.queue.add(obj);
    this.queue.notify();
}
“每个线程都应该有自己的线程”你能解释一下吗? 如果您的意思是队列属于该线程,那么在执行添加后,您将进行轮询并打印您的消息。

每个线程都应该有自己的线程。您能解释更多吗?
如果您的意思是队列属于该线程,则在执行添加操作后,您将进行轮询并打印您的消息。

什么是
队列
?它是某种并发的、可等待的队列吗?BlockingQueue呢?因为Thread.sleep()有帮助,所以您很可能创建了一个竞争条件。你可以发布你的线程是如何创建的吗?你如何确保在执行线程之前队列被填满?@DavidSchwartz队列只是一个简单的队列,不是吗?@JanGroothuijse我不能确保在执行之前队列被填满。这个程序的整体思想是,对象可以在任何时间发送,也可以在运行中发送……什么是
队列
?它是某种并发的、可等待的队列吗?BlockingQueue呢?因为Thread.sleep()有帮助,所以您很可能创建了一个竞争条件。你可以发布你的线程是如何创建的吗?你如何确保在执行线程之前队列被填满?@DavidSchwartz队列只是一个简单的队列,不是吗?@JanGroothuijse我不能确保在执行之前队列被填满。这个程序的整体思想是,对象可以在任何时候发送,也可以在运行中发送……谢谢,我在执行此操作时遇到了这个异常:
线程“thread-0”java.lang.IllegalMonitorStateException
等待()
通知()
仅在
同步的
块中工作谢谢,我在执行此操作时遇到此异常:
线程“thread-0”java.lang.IllegalMonitorStateException中的异常
wait()
notify()
仅在
synchronized
块中工作可能不工作,因为他在线程中保留了一个克隆,因此,即使实际的
队列
引用得到更新,线程也不会得到任何通知,因为它有一个克隆的引用……如果克隆的引用点位于同一个对象上,那么这根本就不是问题。。。但同时你是对的,不清楚这个队列是否是线程安全的。这可能不起作用,因为他在线程中保留了一个克隆,所以即使实际的
队列
引用得到更新,线程也不会得到任何通知,因为它有一个克隆的引用…如果克隆的引用点位于同一个对象上,那么这根本不是问题。。。但同时你是对的,不清楚这个队列是否是线程安全的。