免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: jhsea3do
打印 上一主题 下一主题

这样写线程程序有问题么,附代码 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2006-06-01 10:26 |只看该作者
你这样的多线程是没意义的

可以有很多线程去访问 getNews ,但是 getNews 里的,再启动多线程去争同一个资源,而且谁先争到就用

谁的,这部分是没有意义的..................................

论坛徽章:
0
12 [报告]
发表于 2006-06-01 10:47 |只看该作者
你没看懂我的程序,不和你解释。

论坛徽章:
0
13 [报告]
发表于 2006-06-01 13:46 |只看该作者
原帖由 jhsea3do 于 2006-6-1 09:22 发表
的确即使生成了多个线程也不会影响news的值。

因为实际运行中要并发大量的getNews()请求,怕影响效率。

现在想了一下,直接在生成thread之前把WEB_INTERFACE_CONTENT_NEWS付一个非null值即可。


如果实际生成线程数量不多(少于10个),应该不会影响效率的,除非你在windows xp上运行(因为winxp限制了tcp并发连接数),如果如果真的要synchronized,你这种情况也应该用public static synchronized .. 因为你这个类被创建了很多实例,不同实例之间的非static的方法是不会互相影响的,看来你还没完全理解synchronized的用法。

如果你有一个类MyThreadedClass,生成
MyThreadedClass t1 = new ...
MyThreadedClass t2 = new ...

那么运行 t1.method1(); t2.method1() 完全不会互相影响,除非method1是static的,那么就有影响,static的method不管创建实例与否,都指向同一个内存地址,所以需要synchronized static来防止同时访问。那么非static的方法什么时候需要synchronized呢?

举例:
MyObject o1 = new MyObject();

MyThreadedClass t1 = new MyThreadedClass(o1);
MyThreadedClass t2 = new MyThreadedClass(o1);

public class MyThreadedClass extends Thread {
    public void run() {
        ....
        o1.method2();
        ....
    }
}
为了防止t1和t2两个同时运行的线程同时修改o1里面的数据,这个o1的method2()才是真正需要synchronized的非static类。

楼主考虑性能的话,synchronized也不是最佳方案,可以用线程池来解决问题,java5里面自带了线程池的实现类,用起来很方便。

[ 本帖最后由 perryhg 于 2006-6-1 13:48 编辑 ]

论坛徽章:
0
14 [报告]
发表于 2006-06-01 18:21 |只看该作者
感谢perryhg斑竹的关心和回答。

我解释一下,news是放在多个网站上的内容(实际上我的程序比我在本贴贴出的代码复杂,因为news不是一个字符串而是一个Map,每个网站都有对应的news,实际上我的getNews()方法是带参的。参数决定是那个网站的news,而thread也是多个,Map有多大,thread就有多少),这些网站不定时更新(但不会频繁更新),getWebInterfaceContent()其实一个http query, parse的过程。

getNews()是我方的客户(手机用户)需要调用的动作,如果我在每个getNews()中都去加载getWebInterfaceContent()方法是没有必要的(并且这样返回新闻的速度很慢,要知道来源于网络的数据是不稳定的不可信任的,比如ConnectionTimeOut可能导致执行时间过长),所以我想到了用且仅用一个线程更新news内容。

把getNews()做成成员的方法而不是static的方法是因为这个方法是一个接口方法的实现,不能用static限定。

现在已经去掉了synchronized,写了一个static的方法来获取新闻,并把getNews()作为该static方法的接口封装。

[ 本帖最后由 jhsea3do 于 2006-6-1 18:24 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2006-06-01 18:39 |只看该作者
原帖由 jhsea3do 于 2006-6-1 18:21 发表
感谢perryhg斑竹的关心和回答。

我解释一下,news是放在多个网站上的内容(实际上我的程序比我在本贴贴出的代码复杂,因为news不是一个字符串而是一个Map,每个网站都有对应的news,实际上我的getNews()方法是带 ...

如果是Map的话,应该在更新这个Map的时候用synchronized 代码块
synchronized (newsMap) {
    newsMap.put(xxx, yyy);
}

然后获取的时候也用synchronized 代码块锁定一下,这样就可以保证读和写不会同时发生。
synchronized (newsMap) {
    newsMap.get(xxx);
}

论坛徽章:
0
16 [报告]
发表于 2006-06-02 22:30 |只看该作者
哦,没仔细看....

论坛徽章:
0
17 [报告]
发表于 2006-06-02 22:35 |只看该作者
估计这种是要搞一种类似,单实例的一个维护任务

设个标识值就行了(不用复杂的对象,用基本类型,保证原子性)

论坛徽章:
0
18 [报告]
发表于 2006-06-02 22:41 |只看该作者
原帖由 jhsea3do 于 2006-6-1 09:22 发表
的确即使生成了多个线程也不会影响news的值。

因为实际运行中要并发大量的getNews()请求,怕影响效率。

现在想了一下,直接在生成thread之前把WEB_INTERFACE_CONTENT_NEWS付一个非null值即可。



这也是不行的,还是有可能出现多个实例(不加同步关键字的话)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP