解决共享资源竞争

Java以提供关键字synchronized的形式,为防止资源冲突提供了内置支持。当任务要执行被synchronized关键字保护的代码片段的时候,它将检查锁是否可用,然后获取锁,执行代码,释放锁。

共享资源一般是以对象形式存在的内存片段,但也可以是文件、输入/输出端口,或者是打印机。要控制对共享资源的访问,得先把它包装进一个对象。然后所有要访问这个资源的方法标记为synchronized。如果某个任务处于一个标记为synchronized的方法调用中,那么在这个线程从该方法返回之前,其他所有要调用类中任何标记为synchronized方法的线程都会被阻塞。

synchronized void f()

synchronized void g()

所有的对象都自动含有一个单一的锁(也称为监视器)。当在对象上调用其任意synchronized方法的时候,此对象都被加锁,这时该对象上的其他synchronized方法只有等到前一个方法调用完毕并释放了锁之后才能被调用。对于前面的方法,如果某个任务对对象调用了f(),对于同一个对象而言,就只能等到f()调用结束并释放了锁之后,其他任务才能调用f()和g()。所以,对于某个特定对象来说,其所有synchronized方法共享同一个锁,这可以被用来防止多个任务同时访问被编码为对象内存。

注意,在使用并发时,将域设置为private是非常重要的,否则,synchronized关键字就不能防止其他任务直接访问域,这样就会产生冲突。

一个任务可以多次获得对象的锁,如果一个方法在同一个对象上调用了第二个方法,后者又调用了同一对象上的另一个方法,就会发生这种情况。JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。

针对每个类,也有一个锁,所以synchronized static方法可以在类的范围内防止对static数据的并发访问。

线程池资源竞争问题

11-22

最近开发个小项目,遇到一个困扰了好几天的问题,中间的一个子模块设计是这样的。rnrn有一个数据对象[color=#FF0000] DataObject[/color] ,里面有个更新数据的方法 [color=#FF0000]Update(string m_temp)[/color] ,但是还需要将该数据对象显示在界面上,定期的1秒钟更新显示,为了试界面具有良好的显示效果,故而在线程池中绘制好Image图形,然后用委托更新到UI显示。但是在数据更新的时候显示绘制,就会提示对象被占用。OK,那就来一个资源锁吧[color=#FF0000]MACHINE_OPERATE_LOCK[/color] ,因为数据更新的方法也在线程池中完成的。rnrn代码如下rn1.更新图形的线程池代码rn[code=csharp]rn//线程池的使用测试代码段====================================rn delegate void DelegatePaintMain(Bitmap bitmap);rn private void ThreadPoolPaintMain(object obj)rn rn DelegatePaintMain d = new DelegatePaintMain(rn PicturePaintMain);rn Bitmap bitmap;rn lock (MACHINE_OPERATE_LOCK)rn rn bitmap = GetBackGroundPicture();rn rn //测试代码段rn //pictureBox_Main.BackgroundImage = bitmap;rn this.Invoke(d, bitmap);rn rn[/code]rnrn调用这段代码的代码是,1秒钟调用一次rn[code=csharp]rn//使用线程池的刷新方法rn ThreadPool.QueueUserWorkItem(new WaitCallback(rn ThreadPoolPaintMain),new object());rn[/code]rnrnOK,上述1秒钟显示一次运行良好,没有问题,但是加入数据更新就不一样了,数据更新代码,该方法大约5秒一次,不定时,该方法也是通过线程池调用的rnrn[code=csharp]rn private void ThreadPoolDealWithMainData(object m_Data)rn rn //处理数据并显示,该方法由线程池管理rn string str = m_Data as string;rnrn lock (MACHINE_OPERATE_LOCK)rn rn //更新对象的数据,速度绝对是10ms以内,绝对没有BUG抛出rn DataObject.Updata(str);rn rn rn[/code]rnrn问题来了,该数据对象的更新的时候,应该马上显示出来更新后的结果,最多1秒延迟。但是事实的情况时,经常会出现数据更新阻塞,长达20秒以上,甚至40多秒的阻塞,但是显示的线程池并没有阻塞,还是1秒刷新(用时间方法检测过,确实在运行,只是数据不更新),分析来分析去,最有可能还是线程资源竞争的问题,实在是困扰的很,望大神都来看看,赐教一下,不胜感激啊

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试