启动一个线程后,我们怎么能保持run函数运行?我有很多想法,但我不确定哪个更专业?

时间:2012-10-17 13:24:48

标签: java multithreading networking tcp thread-safety

Thread中调用start()后,您将调用run()类中的Runnable函数。在run()函数中,我希望线程保持不变,只要它从客户端收到“Bye”消息。如果我把它们放在while循环中,它会占用大量的内存,我想我并没有使用线程的强大功能。顺便说一句,我不希望我的线程通过调用Thread.sleep(6000);在run函数中进入睡眠状态。在运行函数中还有其他方法可以保留吗?

  1. 如果答案是加入何处以及如何使用?我应该在运行功能的开头弹出它并保持在那里直到我从客户端发送“再见”吗?

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

  3. 我应该说while(Thread.isAlive)然后通过拨打Thread.stop来收到“再见”时杀死威胁,这有点危险吗?

  4. 这是我的简化代码:

    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()));
    .
    .
    ..
    ...
    }
    

3 个答案:

答案 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();
    }
}