登录 | 注册
首页 精选版块 论坛帮助 论坛牛人 论坛地图 专家问答
CSDN > CSDN论坛 > Java > Java EE
返回列表
管理菜单 结帖 发帖 回复 关注关注
多线程 继承Runable接口,怎样将线程运行完后的结果返回到主线程 [问题点数:40分,结帖人undertones1985] 快速回复只显示楼主关注帖子
多线程 继承Runable接口,怎样将线程运行完后的结果返回到主线程 [问题点数:40分,结帖人undertones1985] 收藏
undertones1985
undertones1985
undertones1985
本版等级:T1
结帖率:97.5%
楼主 发表于: 2010-06-08 14:45:19
大家好,我现在做一个项目只能用java 1.4版本,因此没办法用1.5版本中的Callable接口给主线程提供返回值。
我做的是将各个独立的任务放在多个线程中同时进行,并希望他们在结束后将结果返回到主线程,请问这该怎么做啊,膜拜各路大侠给我指点指点!
更多 0 分享到:
相关主题推荐:
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 回复次数:26
luozhangwen
luozhangwen
luozhangwen
本版等级:T5
#1 得分:0 回复于: 2010-06-08 14:48:05
对我有用[0] 丢个板砖[1] 引用 | 举报 | 管理
moshalanye
moshalanye
宁静-夏天
本版等级:T5
#2 得分:0 回复于: 2010-06-08 14:59:57
天马行空--- 我的qq的签名也是这个 蛮巧的。
主线程中创建一个数据访问安全的对象A,主线程启动的线程thread2初始化时,A作为thread2的初始化参数,thread2在run方法中把操作结果返回给对象A。
主线程在thread2未完成操作时等待就好了,直到等待的thread2运行结束 进行下步操作。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
QQCrazyBoy
QQCrazyBoy
哈特中尉
本版等级:T5
#3 得分:5 回复于: 2010-06-08 15:01:20
自定义的线程跑玩了就会自动去执行主线程啊!
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
Silence_Smile
Silence_Smile
Silence_Smile
本版等级:T5
#4 得分:5 回复于: 2010-06-08 15:06:33
自定义回调接口,子线程执行完后通过回调接口调用主线程中的回调方法
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
moshalanye
moshalanye
宁静-夏天
本版等级:T5
#5 得分:0 回复于: 2010-06-08 15:10:01
to QQCrazyBoy
引用
自定义的线程跑玩了就会自动去执行主线程啊!
你自己测试下,是这样的吗?
线程和线程之间是独立的。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
wwj85523
wwj85523
俊哥123
本版等级:T2
#6 得分:10 回复于: 2010-06-08 15:47:02
主线程里放一个Hashtable ,业务线程把返回结果放进去,主线程里取。
这样就OK了,另Hashtable是线程安全的,不需要另外加锁
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
guliangliang
guliangliang
艾瑞儿
本版等级:T2
#7 得分:0 回复于: 2010-06-08 16:57:47
学识浅薄,不太懂,学习下
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
potahai
potahai
potahai
本版等级:T3
#8 得分:0 回复于: 2010-06-08 17:21:38
继续关注
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
undertones1985
undertones1985
undertones1985
本版等级:T1
#9 得分:0 回复于: 2010-06-08 18:42:55
楼上的说的方法我还是不太懂,把问题再明确一下:
每个线程结束都会得到一个List类型的数据,然后主线程需要创建一个更大的List类型的变量,把各个子线程的List数据保存进去,我就是这不太懂怎么实现,咋样创建Hashtable实现呢,况且我的进程数是根据输入任务不同,需要变化的,请再次赐教,在线等!
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
undertones1985
undertones1985
undertones1985
本版等级:T1
#10 得分:0 回复于: 2010-06-08 18:48:24
引用 2 楼 moshalanye 的回复:
天马行空--- 我的qq的签名也是这个 蛮巧的。
主线程中创建一个数据访问安全的对象A,主线程启动的线程thread2初始化时,A作为thread2的初始化参数,thread2在run方法中把操作结果返回给对象A。
主线程在thread2未完成操作时等待就好了,直到等待的thread2运行结束 进行下步操作。
请问一下,Runable接口中的run()函数是不允许有返回值的,如何返回?谢谢!
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
mhl1003
mhl1003
mhl1003
本版等级:T2
#11 得分:10 回复于: 2010-06-08 19:15:15
引用 10 楼 undertones1985 的回复:
引用 2 楼 moshalanye 的回复:
天马行空--- 我的qq的签名也是这个 蛮巧的。
主线程中创建一个数据访问安全的对象A,主线程启动的线程thread2初始化时,A作为thread2的初始化参数,thread2在run方法中把操作结果返回给对象A。
主线程在thread2未完成操作时等待就好了,直到等待的thread2运行结束 进行下步操作。
请问一下,Run……
设置一个static静态的变量就可以实现结果共享了。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
katasoft
katasoft
katasoft
本版等级:T4
#12 得分:0 回复于: 2010-06-08 19:16:10
所有子线程都将结果写到公共的缓冲区中(注意并发问题),在启动子线程后,将主线程挂起(wait),直到所有子线程结束后唤醒主线程,此时便可以获取缓冲区中各个子线程写入的内容(相当于子线程饭后的结果)。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
undertones1985
undertones1985
undertones1985
本版等级:T1
#13 得分:0 回复于: 2010-06-08 19:52:10
引用 11 楼 mhl1003 的回复:
引用 10 楼 undertones1985 的回复:
引用 2 楼 moshalanye 的回复:
天马行空--- 我的qq的签名也是这个 蛮巧的。
主线程中创建一个数据访问安全的对象A,主线程启动的线程thread2初始化时,A作为thread2的初始化参数,thread2在run方法中把操作结果返回给对象A。
主线程在thread2未完成操作时等待就好了,直到等待的thr……
我试过了,返回的是空值。静态变量只是对于许多类的实例可以这样实现数据共享,但是在多线程中式一个线程一个类的实例,这样做是不行的!!!
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
moshalanye
moshalanye
宁静-夏天
本版等级:T5
#14 得分:10 回复于: 2010-06-08 20:40:33
汗! 楼主我随便写下 大概是这个思路,我写的是伪代码。
你自己再去改下吧
main(){
Map datas = new Hashedtable();
MyThreadRun run = new MyThreadRun();
run.setDatas(datas);
Thread tt = new Thread(run);
tt.start();
while(!"result is ok".equal(datas.get("status"))){
try{
Thread.sleep(10000);
}catch(Exception){
//todo
}
}
//或者使用join 具体的看下api
tt.join();
Object result = run.get("result");
//dosomething
}
static Class MyThreadRun implements Runable{
Hashedtable datas;
public void setData(Map data){
this.datas = data;
}
run(){
//execute get the result
this.datas.put("result",result);
this.datas.put("status","result is ok");
}
}
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
wwj85523
wwj85523
俊哥123
本版等级:T2
#15 得分:0 回复于: 2010-06-08 21:33:11
Java code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
main(){
HashTable datas = new HashTable();
MainThread mainThread=new MainThread(datas);
mainThread.start();
//这里的子线程可以多个
MyThreadRun run = new MyThreadRun();
run.setDatas(datas);
Thread tt = new Thread(run);
tt.start();
}
Class MyThreadRun implements Runable{
Hashedtable datas;
public void setData(Map data){
this.datas = data;
}
run(){
//execute get the result
this.datas.put("result",result);
this.datas.put("status","result is ok");
}
}
class MainThread extends Thread{
Hashtable table;
public MainThread(Hashtable table){
this.table=table;
}
public void run(){
while(true){
Thread.sleep(1000l);
List result=table.remove("result");
if(result!=null){
//dosomething
}
}
}
}
参照楼上的代码,随便改下,楼上的大哥不要生气哈。- -!!
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
xusenjian
xusenjian
xusenjian
本版等级:T2
#16 得分:0 回复于: 2010-06-08 21:54:34
概是这个思路,我写的是伪代码
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
moshalanye
moshalanye
宁静-夏天
本版等级:T5
#17 得分:0 回复于: 2010-06-09 08:54:51
to wwj85523
你该成三个线程了,main方法执行的也有一个线程,不过这么写楼主可能更好理解。
不过
引用
while(true){
Thread.sleep(1000l);
List result=table.remove("result");
if(result!=null){
//dosomething
}
要改一下,这样写线程不会死了,一般都是使用状态量来控制 while(isAlive)
if(result!=null){
//dosomething
isAlive = false;
}
这样比较好,也可以使用Thread 内置的状态 interrupted
while(isInterrupted()){
//dosomething
interrupted();
}
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
undertones1985
undertones1985
undertones1985
本版等级:T1
#18 得分:0 回复于: 2010-06-09 10:15:41
引用 14 楼 moshalanye 的回复:
汗! 楼主我随便写下 大概是这个思路,我写的是伪代码。
你自己再去改下吧
main(){
Map datas = new Hashedtable();
MyThreadRun run = new MyThreadRun();
run.setDatas(datas);
Thread tt = new Thread(run);
tt.start();
……
你这样写是针对只有一个子线程的,如果有多个子线程在同时执行,而且每个子线程结束任务并返回的时间是不同的,但是都返回值的的Hashtable表中的状态标记 "status" = finish.这样对于你的程序就只能返回最开始的一个线程值了。
还有没有更好的方法呢?谢谢
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
SDMRauquin
SDMRauquin
SDMRauquin
本版等级:T6
#19 得分:0 回复于: 2010-06-09 10:23:52
要带返回值的线程。需要JDK1.5以上
有Callable 这个
详细的用法你去看资料。
给你看看我简单的应用。
根据返回值判断是否跳出循环的
Java code
?
1
2
3
4
5
6
7
8
9
10
11
12
Callable callable = new ReadInfoTimerTask(unicode, messages);
Future future = null;
int i = 1;
while(messages[2].trim().equals("")) //unicode is empty
{
future = SSP.scheduledExecutor.schedule(callable, scanTime, TimeUnit.SECONDS);
messages = (String[])future.get();
i++;
if(i>scanNO)
// messages[3] = "timeOut";
break;
}
这个是线程
Java code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ReadInfoTimerTask implements Callable {
private String key;
private String[] messages;
public ReadInfoTimerTask(String unicode, String[] messages){
this.key = unicode;
this.messages = messages;
}
public String[] call() throws Exception{
if(SSP.resultList.get(key)!=null)
{
messages = SSP.resultList.get(key);
SSP.resultList.remove(key);
}
return messages;
}
}
这只是部分的代码,不能直接复制使用,仅供参考
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
SDMRauquin
SDMRauquin
SDMRauquin
本版等级:T6
#20 得分:0 回复于: 2010-06-09 10:27:41
说了才看见问题。。不能JDK1.5
当我没说。。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
moshalanye
moshalanye
宁静-夏天
本版等级:T5
#21 得分:0 回复于: 2010-06-09 10:30:48
楼主这个是伪代码,你怎么去判定是不是子线程都执行完毕,完全可以自己设计嘛。
例如:引用计数器的方式。main thread 开启几个 son thread,就在计数器中+ji,
son thread 运行结束,对计数器-1,当减到0的时候,main thread 判定 son thread 执行完毕,
开始执行。
引用计数器 就是一个线程共享的 线程安全的数据资源。之前的代码也给你了,你可以参照。
引用计数器,在 lucene 2.32中 IndexReader 有引用计数器代码,当然有计数器代码的地方应该很多。
你可以参照下。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
SDMRauquin
SDMRauquin
SDMRauquin
本版等级:T6
#22 得分:0 回复于: 2010-06-09 10:36:47
public static ConcurrentHashMap<String, List[]> resultList = new ConcurrentHashMap<String, List[]>(); //ConcurrentHashMap支持多线程并发
每个线程创建的时候,生成一个UniID保存成key。
子线程返回的结果,根据这个key保存进resultList。
主线程每隔一段时间去遍历这个list
for(Map.Entry<String, List[]> entry : XXX.resultList.entrySet())
{
if(XXX)
{
method(entry.getValue(),entry.getKey());
}
XXX.resultList.remove(entry.getKey());
}
处理完移出list
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
moshalanye
moshalanye
宁静-夏天
本版等级:T5
#23 得分:0 回复于: 2010-06-09 11:08:15
ConcurrentHashMap 不仅仅是支持多线程并发了,它还提供了散列 sagement 的实现方式,分离了 segement 访问的同步锁,从而加速了同步访问速度。
改进了以往 HashTable 或者 Collections.syn..(Map) 只提供一个 segement 和 单一的同步锁的情况。
楼上的朋友很热衷 concurrent 包列。连续的几个建议都是使用这个包。
这个地方没必要使用 ConcurrentHashMap,有点杀鸡用牛刀的感觉,简洁就好,自己设计成线程安全就可以了。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
BearKin
BearKin
BearKin
本版等级:T7
Blank
#24 得分:0 回复于: 2010-06-09 11:48:57
Java code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package thread;
import java.util.ArrayList;
import java.util.List;
public class NoCallable {
public static void main(String[] args) {
List<TestThread> list = new ArrayList<TestThread>();
for (int i = 0; i < 4; i++) {
TestThread testThread = new TestThread(9999999999L);
testThread.start();
list.add(testThread);
}
boolean isLoop = true;
while (isLoop) {
try {
Thread.sleep(1000 * 1);
isLoop = false;
for (TestThread testThread : list) {
System.out.println(testThread.isAlive());
if (testThread.isAlive()) {
isLoop = true;
}
}
System.out.println();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (TestThread testThread : list) {
System.out.println(testThread.getResult());
}
}
}
class TestThread extends Thread {
private long loopNum;
private int result = 0;
public TestThread(long loopNum) {
this.loopNum = loopNum;
}
@Override
public void run() {
long currentNum = loopNum;
boolean isOver = false;
while (!isOver) {
if (currentNum < 0) {
isOver = true;
}
result++;
currentNum = currentNum - 2;
}
}
public long getLoopNum() {
return loopNum;
}
public void setLoopNum(long loopNum) {
this.loopNum = loopNum;
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
}
这个不用Callable 线程这方面俺知识太少了 所以你凑货着看吧。。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
undertones1985
undertones1985
undertones1985
本版等级:T1
#25 得分:0 回复于: 2010-06-11 21:33:50
谢谢大家,我已经搞定了,就如同上面说的那样。给线程类设置一个静态变量,就可以实现线程间的数据共享,然后再创建一个HashTable就可以实现将此线程内的数据传递给主线程。最后对刚起的各个子线程利用Join()方法,使他们全部允许完再回到主线程,就可以完成我的功能,在此谢谢大家。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
purple117
purple117
purple117
本版等级:T1
#26 得分:0 回复于: 2012-05-18 13:52:32
可以贴出你的能成功实现的代码吗? 谢谢
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
返回列表
管理菜单 结帖 发帖 回复 关注关注
本帖子已过去太久远了,不再提供回复功能。
公司简介|招贤纳士|广告服务|银行汇款帐号|联系方式|版权声明|法律顾问|问题报告|合作伙伴|论坛反馈
网站客服杂志客服微博客服
[email protected]|北京创新乐知信息技术有限公司 版权所有|江苏乐知网络技术有限公司 提供商务支持
京 ICP 证 070598 号|Copyright © 1999-2014, CSDN.NET, All Rights Reserved GongshangLogo