解决共享资源竞争

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数据的并发访问。

阅读更多
想对作者说点什么?

博主推荐

换一批

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