返回信息流有多个线程,每个线程监听特定版面的新帖,这些线程因为不停止,所以每个线程都使用`while(true)`,现在的问题貌似是进入到某个进程就不会再执行其他线程了。想问问是这样吗?
这是一条镜像帖。来源:北邮人论坛 / java / #51143同步于 2016/6/22
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
关于线程的问题
wht
2016/6/22镜像同步20 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
【 在 wht 的大作中提到: 】
: 有多个线程,每个线程监听特定版面的新帖,这些线程因为不停止,所以每个线程都使用`while(true)`,现在的问题貌似是进入到某个进程就不会再执行其他线程了。想问问是这样吗?
我猜“进程”是个笔误吧。Java程序一般不用多进程。假设是多个线程,每个线程监听一个版。
如果是多线程,那么即使每个线程都在执行while(true),那么各个线程也会独立地执行的。这尽管放心好了。
如果你发现所有的线程都不再继续执行,就这样做:
1. 打印日志:每个进程在while(true)里面打印日志。如果是监听论坛的版的话,我猜实现的方法是每隔一段时间发送一个http请求。这样的话,在发送请求之前和之后记录日志。一般日志框架会连thread的name一起打印出来。name在thread创建的时候可以设置。其实很有可能是服务器一直不给响应,客户端又没有设置超时。
2. 如果是真的都不动了,而不只是等待时间太长,那么,检查有没有死锁。一般来说,如果一个线程会试图获得两个不同的锁,那么就很可能死锁了。
3. 如果确信自己的代码没问题,检查你所用到的库。
现在信息不足。如果能说说你用了什么库,以及“监视”的策略,最好可以帖代码,那就更容易找错了。如果几个线程之间需要同步,或者对共享数据的访问,最好也说说同步的策略。
暖神~~
没有你想的那么难。。。我只是想简单的写个抢沙发的代码。一个线程监听一个版,程序第一次得到的本版最大文章数赋给局部变量currentPost,之后每隔一段时间检查一次,得到的如果大于这个值,更新它,并且发表文章。代码在下面:
public void run() {
String appendRequest = "oauth_token=" + accessToken;
HttpGet get = new HttpGet("http://bbs.byr.cn/open/board/" + boardname + ".json?mode=6&" + appendRequest);
int currentPos = 0;
try {
while (true) {
// Thread.sleep(30000);
HttpResponse response = httpClient.execute(get);
String content = EntityUtils.toString(response.getEntity());
JSONObject object = JSONObject.fromObject(content);
JSONArray array = JSONArray.fromObject(object.getString("article"));
for (int i = 0; i < array.size(); i++) {
if ((Integer) array.getJSONObject(i).get("position") > currentPos) {
// currentPos = (Integer) array.getJSONObject(i).get("position");
String title = (String) array.getJSONObject(i).get("title");
int reid = (Integer) array.getJSONObject(i).get("reply_id");
postArticle(title, reid, countPost);
}
}
}
} catch (IOException e) {
e.printStackTrace();
// } catch (InterruptedException e) {
// e.printStackTrace();
}
}
我有两个困惑:
1、currentPost这个值在每个线程中是独立的么?没法调试多线程,所以我不是很清楚
2、while(true)里面如果让该线程sleep一段时间,还需要唤醒它么,时间到了它会不会自动唤醒自己?
以及,现在测试的结果好像是程序发帖超过两帖之后可以发送请求,但是服务器好像不会给回应。为啥web或者客户端可以不断发请求,它是根据什么来判断的。。。
【 在 nuanyangyang 的大作中提到: 】
: 我猜“进程”是个笔误吧。Java程序一般不用多进程。假设是多个线程,每个线程监听一个版。
: 如果是多线程,那么即使每个线程都在执行while(true),那么各个线程也会独立地执行的。这尽管放心好了。
: 如果你发现所有的线程都不再继续执行,就这样做:
: ...................
抓住证据了
【 在 wht 的大作中提到: 】
: 暖神~~
: 没有你想的那么难。。。我只是想简单的写个抢沙发的代码。一个线程监听一个版,程序第一次得到的本版最大文章数赋给局部变量currentPost,之后每隔一段时间检查一次,得到的如果大于这个值,更新它,并且发表文章。代码在下面:
: [code=java]
: ...................
1. currentPos是独立的。它是局部变量,是不能共享的。
2. Thread.sleep(30000)在30秒钟后会自己醒来。不用唤醒。
但是,你的程序sleep的时机是回帖以后。如果发完board的get请求,但没有新帖,你的程序会立即再次向服务器发送get请求,中间没有任何休息。这样我觉得服务器会被你的程序累死的。
【 在 wht 的大作中提到: 】
: 暖神~~
: 没有你想的那么难。。。我只是想简单的写个抢沙发的代码。一个线程监听一个版,程序第一次得到的本版最大文章数赋给局部变量currentPost,之后每隔一段时间检查一次,得到的如果大于这个值,更新它,并且发表文章。代码在下面:
: [code=java]
: ...................
多谢暖神,代码已修改。但是我用如下语句传入不同的版面,按道理每个线程的currentPost初始都是0,因此每个版面至少都会发一篇帖子。事实上只会在随机的一个版面发帖子,然后就卡住了[ema1]
for (int i = 0; i < bms.size(); i++) {
ListenNewPostThread lnt = new ListenNewPostThread(countPost, httpClient, accessToken, refreshToken, bms.get(i), replyContent);
lnt.start();
}
结果:
【 在 nuanyangyang 的大作中提到: 】
: 1. currentPos是独立的。它是局部变量,是不能共享的。
: 2. Thread.sleep(30000)在30秒钟后会自己醒来。不用唤醒。
: 但是,你的程序sleep的时机是回帖以后。如果发完board的get请求,但没有新帖,你的程序会立即再次向服务器发送get请求,中间没有任何休息。这样我觉得服务器会被你的程序累死的。
: ...................
打印日志了吗?在httpClient.execute前后各打印一个日志试试看?
【 在 wht 的大作中提到: 】
: 多谢暖神,代码已修改。但是我用如下语句传入不同的版面,按道理每个线程的currentPost初始都是0,因此每个版面至少都会发一篇帖子。事实上只会在随机的一个版面发帖子,然后就卡住了
: [code=java]
: for (int i = 0; i < bms.size(); i++) {
: ...................
打码好累。。
这样看来我反复请求的时候只会给我一次回应
但是第一次请求以后为啥也只能在一个版面发文章,搞不懂。。
打印currentPost是在for循环之后,因此好几个线程都没有执行for循环,所以没发帖。。。同样困惑中。。。
【 在 nuanyangyang 的大作中提到: 】
: 打印日志了吗?在httpClient.execute前后各打印一个日志试试看?