iteye_17041 2012-10-11 11:27
浏览 267
已采纳

多线程,保证用户只存在一个线程。困扰很久,实在没有办法

servlet,用户请求的地址。当用户请求之后,会调用control.start();进入一个耗时的操作,循环等待。直到超时或者是打断循环退出继续执行。问题出在else语句块,原来意思是如果是刷新,结束该用户的上一个等待线程,该次请求挂起,这样保证了一个用户只存在一个线程。执行顺序应该是先结束上一个线程再new一个新线程。但执行的接是先new一个线程再结束上一个进程。结束线程我也用线程来控制,但还是不行。希望大家能帮我解决一下、谢谢。这个问题困扰很久了。[code="java"]PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String receiver = String.valueOf(session.getAttribute("User"));

        ChatControl control = null;
        if (ChatListener.threadMap.get(receiver) == null) {
            System.out.println("============================ threadMap.get(receiver) == null");
            control= new ChatControl();
            ChatListener.threadMap.put(receiver , control);//线程对象塞进map
            control.start();//启用线程

// control.join();
ChatListener.threadMap.remove(receiver);
}else {
System.out.println("============================ threadMap.get(receiver) != null");
//如果是刷新,结束上一个长连接,此连接挂起
StopThreadControl stopThread = new StopThreadControl();
stopThread.setPriority(Thread.NORM_PRIORITY+2);
stopThread.setUser(receiver);
stopThread.start();
stopThread.join();//等待停止线程之后再执行new新的线程,但程序没有按照这样执行
/*
control = new ChatControl();
control.update(receiver);//有可能抢cpu资源引起的,无法控制
control = null;
*/
//挂起
ChatControl control2 = new ChatControl();
ChatListener.threadMap.put(receiver, control2);
control2.start();
// control2.join();
ChatListener.threadMap.remove(receiver);
}
ChatHelper.updateChatToReceived(receiver);//更新到已收到[/code]

ChatControl.java 继承 Thread,run是一个耗时的操作。用户请求会进入此等待
[code="java"]public void run()
{ String threadName = Thread.currentThread().getName();
log.info("当前启动线程是:"+threadName);
Date newDate = DateUtil.getNowDateAndTime();
int i = 0;
while(!done){
try {
System.out.println("循环ing。。。。"+i++);
//睡眠1秒继续等待
sleep(1*1000);
//5分钟返回一次,避免资源一直在占用
if(DateUtil.getTwoTimeSub(DateUtil.getNowDateAndTime(), newDate) >= 5){
break ;
}
} catch (Exception e) {
log.error(Constants.getExceptionString("run()", ChatControl.class));
break;//退出
}
}
log.info("当前结束线程:"+threadName);
}[/code]

StopThreadControl 继承Thread, 让上一个线程退出循环,结束进程
[code="java"] String user;
public void run() {
System.out.println("进入StopThreadControl..........................");
ChatControl control= (ChatControl) ChatListener.threadMap.get(user);
ChatListener.threadMap.remove(user);
if (control != null ) {
control.breakThread();
System.out.println("打断循环.........................................");
}
return ;
}[/code]

[code="java"]public class ChatListener {
static public Map threadMap = new HashMap() ;//保存线程

}[/code]

我查了很多关于多线程编程的资料,但还是不会很好运用。还有多线程异步调用。需要使用内部类吗?希望大家能帮我解决一下,指出代码的问题所在,谢谢、

  • 写回答

8条回答 默认 最新

  • yuwenchun 2012-10-11 22:34
    关注

    你这需求似乎没有必要重新new线程吧!
    假设线程ChatControl有如下状态:初始态、运行态、结束态。
    当触发刷新的时候,直接将线程ChatControl状态由运行态回退
    为初始态并重新进入运行态不就得了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(7条)

报告相同问题?

悬赏问题

  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)