免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2564 | 回复: 17
打印 上一主题 下一主题

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-05-31 10:57 |只看该作者 |倒序浏览
现在有一个新闻的web接口,我需要每隔20分钟去调用getWebInterfaceContent方法来更新新闻。

不想写线程类,直接在一个方法里面new了一个thread对象。

请问我这样写会有问题么,需不需要用synchronized关键字,注:getWebInterfaceContent是一个static的方法。



  1.         /**
  2.          * WEB_INTERFACE_CONTENT_NEWS
  3.          */
  4.         private static String WEB_INTERFACE_CONTENT_NEWS = null;
  5.        
  6.         /**
  7.          * WEB_INTERFACE_CONTENT_NEWS
  8.          */
  9.         private static String WEB_INTERFACE_COMMAND_NEWS = "news";

  10.         /**
  11.          * 取得最新新闻
  12.          * @return
  13.          */
  14.         synchronized public String getNews() {
  15.                 if(null == WEB_INTERFACE_CONTENT_NEWS) {
  16.                         // 设置当前新闻
  17.                         WEB_INTERFACE_CONTENT_NEWS
  18.                                 = getWebInterfaceContent(
  19.                                         WEB_INTERFACE_COMMAND_NEWS);
  20.                         // 设置每隔一定时间取得最新新闻
  21.                         Thread t = new Thread() {
  22.                                 long timeS = System.currentTimeMillis();
  23.                                 long timeE = System.currentTimeMillis();
  24.                                 long offset = 20*60*1000;
  25.                                 public void run() {
  26.                                         for(;;) {
  27.                                                 if((timeE - timeS) % offset == 0) {
  28.                                                         WEB_INTERFACE_CONTENT_NEWS
  29.                                                                 = getWebInterfaceContent(
  30.                                                                                 WEB_INTERFACE_COMMAND_NEWS);
  31.                                                         logger.debug("NEWS, id = " + timeS);
  32.                                                 }
  33.                                                 timeE = System.currentTimeMillis();
  34.                                         }
  35.                                 }
  36.                         };
  37.                         t.start();
  38.                 }
  39.                 return WEB_INTERFACE_CONTENT_NEWS;
  40.         }

复制代码

论坛徽章:
0
2 [报告]
发表于 2006-05-31 12:08 |只看该作者
我有点建议:
1)用这种忙线程定时是不是很耗费cpu
2)if((timeE - timeS) % offset == 0)  这种判断太严格,如果由于线程切换丢毫秒那就会出问题

论坛徽章:
0
3 [报告]
发表于 2006-05-31 12:26 |只看该作者
是了,刚才粗心了,现在改成了时间阻塞方式

  1. while(true) {
  2.                                                 WEB_INTERFACE_CONTENT_NEWS
  3.                                                         = getWebInterfaceContent(
  4.                                                                 WEB_INTERFACE_COMMAND_NEWS);
  5.                                                 logger.debug("NEWS, id = " + timeS);
  6.                                                 try { Thread.sleep(offset); }
  7.                                                 catch (Exception ex) {logger.error("thread sleep err", ex);}
  8.                                         }

复制代码

论坛徽章:
0
4 [报告]
发表于 2006-05-31 12:47 |只看该作者
同步这里我想说的是:
读者之间应该不需要互斥.但读写之间要互斥的吧,也就是在更新新闻的时候是不能读新闻(getWebInterfaceContent),所以应该在新闻的读写那里设置读写锁.祥见操作系统中读者写者问题

论坛徽章:
0
5 [报告]
发表于 2006-05-31 13:16 |只看该作者
getWebInterfaceContent(cmd)是一个static方法,且新闻更新时不影响其返回值,并且返回值不会为null。

getNews()我用synchronized关键字的目的是怕产生多余的线程进程,该方法的目的是永远只有一个线程来更新WEB_INTERFACE_CONTENT_NEWS,默认没有线程来更新,当getNews()方法被第一次调用后才会启动该线程。

论坛徽章:
0
6 [报告]
发表于 2006-05-31 13:21 |只看该作者
楼主虽然启用了一个线程来读取新闻,对你主程序来说,你是多开了一个线程,但是对你的读新闻的程序来说,实际上还是单线程处理,并没有别的线程来同时来读取新闻,所以这里的synchronized也没什么必要。

synchronized 主要用于你使用多个线程同时来读取新闻的时候,确保只有一个网络读操作在进行中。

[ 本帖最后由 perryhg 于 2006-5-31 13:23 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2006-05-31 13:51 |只看该作者
getNews()是WebContentDAO的一个成员方法。

比如我可能在A对象一个方法中new了一个WebContentDAO对象wc0, 又在B对象一个方法中new了一个WebContentDAO对象wc1.

如果我不用synchronized关键字。假如wc0.getNews()和wc1.getNews()先后执行,正好wc0因为网络问题没有及时得到返回值,这个时候WEB_INTERFACE_CONTENT_NEWS仍是null, 正巧wc1也要执行了,结果就new了两个Thread对象。可能么?

论坛徽章:
0
8 [报告]
发表于 2006-05-31 23:39 |只看该作者
假如是多个线程,和多个新闻文件,判断相同新闻ID互斥是有意义的

但现在多线程去争同一个任务?而且第一个抢到的线程就执行,没抢到的就不执行?

你这样写的多线程有意义吗?

就要要写,也最好符合把 synchronized 块里需要执行的内容减到最少。。。。

论坛徽章:
0
9 [报告]
发表于 2006-06-01 06:09 |只看该作者
原帖由 jhsea3do 于 2006-5-31 13:51 发表
getNews()是WebContentDAO的一个成员方法。

比如我可能在A对象一个方法中new了一个WebContentDAO对象wc0, 又在B对象一个方法中new了一个WebContentDAO对象wc1.

如果我不用synchronized关键字。假如wc0.getN ...

照你这么说的确是多线程,但是你仅仅是读取数据的话,也没什么必要用synchronized了,就好比你可以同时用两个浏览器窗口打开同一个网页,这个不会互相影响的吧,线程锁及互斥锁主要用在有写更新的操作里面,避免一个用户读取到别人更改了一半的的数据。

论坛徽章:
0
10 [报告]
发表于 2006-06-01 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