8

Thread调用之后start(),你知道它会调用类run()中的函数Runnable。在run()函数中,我希望线程只要从客户端接收到“Bye”消息就一直存在。如果我把它们放在while循环中,我认为它会占用大量内存,而且我没有使用线程的力量。顺便说一句,我不希望我的线程通过调用在运行函数中休眠。Thread.sleep(6000);还有其他方法可以留在运行函数中吗?

  1. 如果答案是加入在哪里以及如何使用它?我是否应该在运行函数开始时弹出它并保持在那里直到我从客户端发送“Bye”?

  2. 我应该说while((request=in.readLine())!=null){吗?它不起作用,因为我认为它会失去与客户端的连接,或者更好地说是客户端失去连接?

  3. 当我接到“再见”的电话时,我应该说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()));
.
.
..
...
}
4

3 回答 3

10

在最简单的情况下,让你的 run 方法完成它的工作并在适当的时候终止,如下所示:

public void run() {
    boolean running = true;
    while(running) {
        running = doWork();
        if (Thread.interrupted()) {
            return;
        }
    }
}

此处,当 doWork() 方法返回 false 时,该过程停止。让你的线程被中断也是很好的风格,特别是如果它需要运行很长时间,请参阅本教程。为了使这些工作,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;
    }
}

Worker 在被打断或工作完成时结束。ThreadManager 也可以通过调用 stopRunning() 方法请求 Worker 停止。

如果您的线程工作结束,它也可以调用 ThreadManager 上的 wait() 方法。这会暂停线程,直到它被通知有新的工作要做。当新工作到达时,ThreadManager 应该调用 notify() 或 notifyAll()(在本例中,ThreadManager 用作监视器)。

使用这种方法,您可以使 Worker 保持简单,并且只关心完成工作。ThreadManager 确定线程的数量并为它们提供工作,但不需要知道实际工作的细节。更进一步的做法是将“工作”也拆分为一个单独的类,您可以将其称为 Job。这方面的一个例子可以在我的网络爬虫示例中找到。这对于将新工作从 ThreadManager 传递到工作线程可能很有用。

编辑:澄清:如果线程不做任何工作,只需要等待某些条件,不要使用迭代等待,而是使用等待/通知(请参阅我给出的 webcrawler 示例)或简单的回调条件出现。

于 2012-10-17T14:53:19.277 回答
4

我知道这已经晚了,但这是一个更好的实现,并且通过忙等待来避免大量 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();
    }
}
于 2015-03-28T02:11:19.243 回答
2

只是returnrun()你得到"bye"

于 2012-10-17T13:27:55.237 回答