Java 取消长轮询循环的并发性问题

Java 取消长轮询循环的并发性问题,java,android,multithreading,synchronization,Java,Android,Multithreading,Synchronization,我有一个问题,我希望我能通过写这个问题来解决,但如果没有,我会发帖,看看是否有人能帮忙 我正在使用一个客户端库(我觉得写得很糟糕)与一个实时聊天服务器进行交互,该服务器使用COMET风格的HTTP长轮询。我在某些情况下取消长轮询时遇到问题,我怀疑可能需要添加一些并发处理代码,但由于以下原因,我发现很难找到最好的方法 订阅代码(初始化长轮询)作为一个大循环实现,如下所示 doLongPoll() { while(true) } //IF channel field

我有一个问题,我希望我能通过写这个问题来解决,但如果没有,我会发帖,看看是否有人能帮忙

我正在使用一个客户端库(我觉得写得很糟糕)与一个实时聊天服务器进行交互,该服务器使用COMET风格的HTTP长轮询。我在某些情况下取消长轮询时遇到问题,我怀疑可能需要添加一些并发处理代码,但由于以下原因,我发现很难找到最好的方法

订阅代码(初始化长轮询)作为一个大循环实现,如下所示

doLongPoll()
{
    while(true)
    }
        //IF channel field boolean unsubscribe == TRUE, if so BREAK;
        //perform GET request (and store channel HTTPClient used for this call)
        //remove HTTPClient used for this call
        //IF channel field boolean unsubscribe == true, if so BREAK;
        //IF connection problem sleep(1500) then CONTINUE
        //post received data to listeners
    }
}
取消订阅呼叫(将在另一个线程上调用)

我已经隔离了操作交错的问题案例。在我看来,这似乎是由于代码是多线程的,而客户端代码不是线程安全的。此外,管理不善和不重用
httpClient
也无济于事

下面是我遇到的一个问题,即取消订阅呼叫不会阻止下一个getRequest的发生

THREAD 1 (polling)                      THREAD 2
--------                                --------
do unsubscribe check (pass)
                                        unsubscribe called
                                        set unsubscribe = true
                                        check if httpClient saved (none)
perform getRequest (save HttpClient first)
我想知道人们认为解决这个问题的最佳方法是什么(时间有限,所以我不能重写太多的代码!)

为了解决这个问题,我认为我可以使用一个同步块,从线程1上的第一次取消订阅检查一直到
httpClient
在执行实际get请求之前被保存,并使用相同的锁同步取消订阅方法。这在目前是不实际的,因为提到的第一个同步块将在一个方法调用中开始,并在方法调用链的更下游结束(由于lib的编写方式),这感觉非常错误,因此需要进行一些重构

或者我可以只为每个通道而不是每个请求创建一个单个
httpClient
,然后它可能总是被关闭,我可能会忽略同步(我认为)

或者正如下面所建议的,我可以使用中断来达到同样的目的

任何建议将是欢迎的-我会编辑,如果我有任何进展

谢谢

1)将unsubscribe设置为volatile

2) 为了获得更大的保证,请保护访问(读/写)以取消订阅,例如,由于这个问题,我购买了一个信号灯

,发现他们在第7章:取消和关闭中讨论了一个非常类似的问题,可以通过引用进行总结

中断通常是最成功的实现方法 取消

由于HttpClient正在阻止不支持中断的套接字IO,所以我有一个双管齐下的方法。我分配我的
httpClient
,在实际的
httpClient.execute()
调用之前检查中断,并在我的
unsubscribe()
方法中中断线程,然后调用
httpClient.getConnectionManager().shutdown()。这似乎解决了我的问题,是一个非常简单的改变。没有更多的交错问题


我还将布尔值
unsubscribe
字段设置为
volatile
,这是我以前应该做的-但是,仅此一项并不能解决问题

1。布尔值是易变的吗?2.使用中断而不是布尔值不是更容易吗。否,但取消订阅调用已同步,因此线程本地值不应出现问题。2.可能,我昨天在考虑这个问题,但想看看这里有什么建议-我可以走这条路。“取消订阅呼叫是同步的”=>write
unsubscribe=true位于同步块中。但是如果(取消订阅)中断,读
if如何doLongPoll
中的code>,
如果(取消订阅)中断doLongPoll
中的code>不在同步块中否-我不认为将这一行单独放在同步块中会有任何区别,因为当写入同步块退出时,它会重新同步任何线程局部变量。另外,我不认为单凭这一点就无法解决上述问题?要正确共享变量,需要同步读写操作(例如,在布尔值的情况下,可以通过使变量可变来实现)。不过,这并不能解决您的交错问题。谢谢您的回答,但这与@assylias的说法相同,并不能真正解决问题
THREAD 1 (polling)                      THREAD 2
--------                                --------
do unsubscribe check (pass)
                                        unsubscribe called
                                        set unsubscribe = true
                                        check if httpClient saved (none)
perform getRequest (save HttpClient first)