在Thread
中调用start()
后,您将调用run()
类中的Runnable
函数。在run()
函数中,我希望线程保持不变,只要它从客户端收到“Bye”消息。如果我把它们放在while循环中,它会占用大量的内存,我想我并没有使用线程的强大功能。顺便说一句,我不希望我的线程通过调用Thread.sleep(6000);
在run函数中进入睡眠状态。在运行函数中还有其他方法可以保留吗?
如果答案是加入何处以及如何使用?我应该在运行功能的开头弹出它并保持在那里直到我从客户端发送“再见”吗?
我应该说while((request=in.readLine())!=null){
吗?它不起作用,因为我认为它将失去与客户的联系或更好地说客户失去连接?
我应该说while(Thread.isAlive)
然后通过拨打Thread.stop
来收到“再见”时杀死威胁,这有点危险吗?
这是我的简化代码:
while(true)
{
ClientWorker w;
try
{
w = new ClientWorker(serverSocket.accept());
Thread t = new Thread(w);
t.start();
}
...... }
class ClientWorker implements Runnable {
public ClientWorker(Socket incoming)
{
myList = my;
this.incoming = incoming;
}
public synchronized void run()
{
in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
.
.
..
...
}
答案 0 :(得分:8)
在最简单的情况下,让你的run方法完成它的工作并在适当时终止,如下所示:
public void run() {
boolean running = true;
while(running) {
running = doWork();
if (Thread.interrupted()) {
return;
}
}
}
此处,当doWork()方法返回false时,进程停止。允许您的线程被中断也是一种很好的风格,特别是如果它需要长时间运行,请参阅this tutorial。要使其中任何一个工作,doWork()应该定期返回。注意,无法重新启动线程,一旦run方法返回,系统就会回收线程。
如果您需要更多控制线程,可以创建单独的Worker和ThreadManager类。
要让ThreadManager终止Worker,请在Worker中创建一个volatile布尔字段,并定期检查:
public class Worker extends Thread {
private volatile boolean running;
public void run() {
running = true;
while(running) {
running = doWork();
if (Thread.interrupted()) {
return;
}
}
}
public void stopRunning() {
running = false;
}
}
工人在中断或工作完成时结束。此外,ThreadManager可以通过调用stopRunning()方法请求Worker停止。
如果你的线程用完了,它也可以在ThreadManager上调用wait()方法。这会暂停线程,直到通知有新的工作要做。当新工作到达时,ThreadManager应该调用notify()或notifyAll()(在这个例子中,ThreadManager用作监视器)。
通过这种方法,您可以保持工人简单,只关心工作。 ThreadManager确定线程数并使其可用,但不需要知道实际工作的详细信息。更进一步的是将“工作”分成一个单独的类,你可以称之为Job。我的webcrawler example就是一个例子。这对于将新工作从ThreadManager传递给工作线程非常有用。
答案 1 :(得分:2)
return
时,只需run()
的{{1}}
答案 2 :(得分:2)
我知道这已经晚了,但是这是一个更好的实现,并且可以通过忙等待避免繁重的CPU使用 - 当线程等待信号时允许上下文切换。
将信号量设置为0可确保当线程尝试获取继续的权限时,它不会获取并等待。释放信号量时,计数增加1,允许线程继续,计数减少回0。
Semaphore sem = new Semaphore(0);
Worker t = new Worker(sem);
t.start();'
// The thread is now running but waiting, signal the semaphore to start work
sem.release();
public class Worker(Semaphore sem) extends Thread {
public void run() {
sem.acquire();
doWork();
}
}