我有一个带有阻塞队列的Java程序,该程序正在快速填充。有几个线程从队列中获取对象并处理它们。
因为新对象是快速生成的,所以消费线程没有机会等待队列包含对象,总有一个对象在等待。
为了让机器上的其他进程获得CPU时间,是否在消费线程的循环内建议/需要sleep()
?
如果没有,因为操作系统负责分时,当系统运行密集型进程时,系统如何变得无响应或非常慢?
澄清
我询问系统上的其他进程,而不是Java程序的其他线程。
答案 0 :(得分:3)
为了让机器上的其他进程获得CPU时间,是否建议/需要在消费线程的循环内sleep()?
现代操作系统使用preemptive multitasking,因此其他进程将可以访问资源(CPU,内存,I / O带宽......)。
但是,操作系统可能会为这些其他进程分配太少的资源,从而减慢它们的速度。防止这种情况的最简单方法是通过适当地设置流程的优先级来指示调度程序优先考虑其他流程(请参阅Cross-platform way to change java process priority)。或者,为消费者线程设置线程优先级可能就足够了(并通过使用阻塞,大小限制的队列来限制生产者线程)。
相反,即使有可用的CPU,Thead.sleep
也会暂停你的线程,浪费CPU周期。值得注意的是Thread.sleep
具有一定的开销,特别是如果它导致上下文切换。因此,过度频繁地调用Thread.sleep
可能非常浪费。
因此,Thread.sleep
是防止其他进程资源匮乏的次优方法。
答案 1 :(得分:1)
您的主要问题是由于计算机上存在工作负载而无法响应的其他进程。
您可以尝试使用" nice"来改变java进程的优先级。和/或" ionice" (对于与unix相关的操作系统......)
这是一个操作系统级别的问题。
我会避免解决问题"那就像一个像睡觉的黑客那样明显不同的层......
关于进程间锁定的理论不适用于这个问题:
比sleep()和轮询更好的解决方案是等待一些信号量或锁定。
即。有一些监视器对象,让生产者通知,并让消费者等待它。
Object dataReady=new Object();
//Producer:
synchronized (dataReady) { dataReady.notify(); }
//Consumer:
synchronized (dataReady) { dataReady.wait();}
如上所述,您正在使用阻止队列。这已经管理了这种低级多线程同步的东西
//in the consumer, simply:
work=blockingQueue.take();
它将自动等待(使用上述机制或类似的东西),直到一个生产者将产品放入()队列中的产品
答案 2 :(得分:0)
让我们举个例子。这是一个3个线程同时工作的程序。 也许这可以澄清你的问题。
class Thread1 implements Runnable
{
int x=10;
public void run()
{
for (int i = 1 ; i<=12 ; i++)
{
try
{
Thread.sleep(1000);
}
catch(Exception e)
{
}
System.out.println(Thread.currentThread().getName());
}
}
}
class Thread2 implements Runnable
{
int x=10;
public void run()
{
for (int i = 1 ; i<=10; i++)
{
try
{
Thread.sleep(1000);
}
catch(Exception e)
{
}
System.out.println(Thread.currentThread().getName()+"count"+ i);
}
}
}
class Thread3 implements Runnable
{
int x;
public void run()
{
for (int i = 1 ; i<=15; i++)
{
try
{
Thread.sleep(1000);
}
catch(Exception e)
{
}
System.out.println(Thread.currentThread().getName());
}
}
}
class Run
{
public static void main(String args[])
{
Thread3 t1 = new Thread3();
t1.x=50;
Thread tt1 = new Thread(t1,"thread1");
tt1.start();
Thread3 t2 = new Thread3();
t2.x=100;
Thread tt2 = new Thread(t2,"thread2");
tt2.start();
System.out.println(t2.x );
for(int i=1 ;i<=20;i++)
{
System.out.println(Thread.currentThread().getName());
try
{
Thread.sleep(1000);
}
catch (Exception e)
{
}
}
}
}
这里的时间共享由操作系统管理。 根据优先级,os共享其内存,处理能力
how does it happen that a system becomes unresponsive or very slow when intensive processes are running on it?
打开您的任务管理器并单击详细信息,它将向您显示ram如何在不同的应用程序和线程之间分配。操作系统决定首先执行哪个进程,并定义优先级,以便处理器可以对其进行操作。