精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-10-29
在Java上,启动一个线程容易,让一个线程不断运行,也很容易,只要一个while循环,一直做死循环就行了。不过问题来了,那关闭线程怎么办?
先写个例子:
public class TestThread extends Thread { @Override public void run() { while(true){ System.out.println("一直运行"); try { sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } } 这样就可以让线程一直运行了,没错,这样是可以,让线程关闭的最好方法不是使用destroy方法,而是让线程自己结束。这个就是主动式关闭。所以一般都是这样处理一个线程:
public class TestThread extends Thread { private boolean flag = true; @Override public void run() { while(flag){ System.out.println("一直运行"); try { sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void stopThread(){ this.flag = false; } } 当这个线程正在运行时,可以用别的线程调用 stopThread()方法,这个时候flag就变成了false,循环结束,线程也就停止了!不过问题又来了,如果是线程里面是这样子的:你看怎么解决?
package cn.std.run.monitor; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class TestThread extends Thread { private boolean flag = true; @Override public void run() { try { ServerSocket serverSocket = new ServerSocket(50001); Socket socket = null; while (flag) { socket = serverSocket.accept(); //SocketCtrlHandler.processRequest(socket);此处对Socket处理 } } catch (IOException e) { e.printStackTrace(); } } public void stopThread(){ this.flag = false; } } 这个时候,stopThread方法就不行了,因为在
socket = serverSocket.accept(); 处,程序会一直堵塞,就像是在循环里面停止了一样,只有等到新的Socket连接进来了,才能不再堵塞。 于是解决办法又有了:
package cn.std.run.monitor; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; public class TestThread extends Thread { private boolean flag = true; @Override public void run() { try { ServerSocket serverSocket = new ServerSocket(50001); Socket socket = null; while (flag) { socket = serverSocket.accept(); //SocketCtrlHandler.processRequest(socket);此处对Socket处理 } } catch (IOException e) { e.printStackTrace(); } } public void stopThread(){ this.flag = false; try { new Socket("localhost",50001); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { TestThread tt = new TestThread(); tt.start(); sleep(3000); tt.stopThread(); } } 在stopThread方法里面new Socket,让线程不再堵塞,进入下一个循环,但是进入下一个循环判断的时候已经变为false,循环结束,线程停止!
那再来一个例子,线程等待队列:
package cn.std.run.monitor; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.util.LinkedList; public class TestThread extends Thread { private boolean flag = true; private LinkedList<Object> pool = new LinkedList<Object>(); public void add(Object obj){ synchronized (pool) { pool.add(obj); pool.notify(); } } @Override public void run() { Object obj = null; while(flag){ synchronized (pool) { while(pool.isEmpty()){ try { pool.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } obj = pool.remove(0); } dispose(obj); } } public void dispose(Object obj){ System.out.println(obj); } public void stopThread(){ this.flag = false; } public static void main(String[] args) throws InterruptedException { TestThread tt = new TestThread(); tt.start(); sleep(3000); tt.stopThread(); } } 这是一个经常使用的线程排队,如果这时候stopThead不做特殊处理,也不能成功关闭线程, 得这样才行:
public void stopThread(){ this.flag = false; add(""); }原理跟上面的ServerSocket堵塞一样,这个就是我说的主动式关闭!好吧,再加一句,原谅我菜,呵呵~~ 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-10-30
个人觉得这种关闭线程的方法很不好,为何不修改为
public void stopThread(){ this.flag = false; this.interrupt(); } public void stopThread(){ this.flag = false; serverSocket.close(); } public void stopThread(){ this.flag = false; pool.notify(); } |
|
返回顶楼 | |
发表时间:2012-10-30
楼上的解决方案更佳!
|
|
返回顶楼 | |
发表时间:2012-10-30
jxxjee 写道 个人觉得这种关闭线程的方法很不好,为何不修改为
public void stopThread(){ this.flag = false; this.interrupt(); } public void stopThread(){ this.flag = false; serverSocket.close(); } public void stopThread(){ this.flag = false; pool.notify(); } 我觉得就是用interrupt方法会马上中断线程,在多线程访问的时候,可能会导致数据不同步问题,或者说,线程正在执行得起劲,在努力帮你干活呢,你却中途把它给干掉了,那它真实死不瞑目了,主动式关闭就是让它把工作干完,然后安心死去,哈哈! 还有 public void stopThread(){ this.flag = false; pool.notify(); } 这个代码,notify确实是将线程唤醒了,不过pool里面为空,那后面那行代码 obj = pool.remove(0); 就抛出空指针异常了! 我认为是这样 |
|
返回顶楼 | |
发表时间:2012-10-30
jxxjee 写道 个人觉得这种关闭线程的方法很不好,为何不修改为
public void stopThread(){ this.flag = false; this.interrupt(); } public void stopThread(){ this.flag = false; serverSocket.close(); } public void stopThread(){ this.flag = false; pool.notify(); } 关于serverSocket.close()这个解决办法,一般都采用这种法子,不过我没有采用这种法子的另一个原因是因为使用new Socket("localhost",50001);这个方法可以移植成远程关闭serverSocket,就是跨系统的。不要仅仅是局限于一个JVM里面,呵呵,我写的时候是这样想的@ |
|
返回顶楼 | |
发表时间:2012-10-30
这个正是我所提倡的“主动式关闭”,核心思想就是:别让线程死不瞑目,应该让其安心死去,所谓逝者如斯夫,死者为上,哈哈,我扯淡
|
|
返回顶楼 | |
发表时间:2012-10-30
顶楼主,顺便问一下,如果是
public void run() { while (true) { String responsecode = reader.readLine(); } } 流的等待读取阻塞的情况该怎么办 |
|
返回顶楼 | |
发表时间:2012-10-30
最后修改:2012-10-30
385104182 写道 顶楼主,顺便问一下,如果是
public void run() { while (true) { String responsecode = reader.readLine(); } } 流的等待读取阻塞的情况该怎么办 这个你就不用这样读取嘛,我经常都这样读 public void run(){ String line = null; String responsecode; while((line = reader.readLine())!=null){ responsecode+=line; } } 这个读完就关闭了,不知道你上面那个是用来做什么的, 也不知道我有没有理解错误,呵呵,多谢围观 |
|
返回顶楼 | |
发表时间:2012-10-30
385104182 写道 顶楼主,顺便问一下,如果是
public void run() { while (true) { String responsecode = reader.readLine(); } } 流的等待读取阻塞的情况该怎么办 还有你这个是在不断读取,并没有堵塞,只是在不断循环而已!你可以打印一下responsecode看看 |
|
返回顶楼 | |
发表时间:2012-10-30
sziitjiang 写道 385104182 写道 顶楼主,顺便问一下,如果是
public void run() { while (true) { String responsecode = reader.readLine(); } } 流的等待读取阻塞的情况该怎么办 还有你这个是在不断读取,并没有堵塞,只是在不断循环而已!你可以打印一下responsecode看看 另一端不写数据,这边等待读的时候就是阻塞啊 |
|
返回顶楼 | |