读后感:
线程同步有2种机制,
一,锁对象+条件对象
二,内部对象锁
锁对象+条件对象:
首先是一个显式的锁,个人觉得是细粒度的保护代码片段,比如一个方法 使用了显示锁,那么线程要进入保护代 码块,必须获得这个锁对象,才可以。说是细粒度的说明其它的方法,可以进入,因为它是显式锁。
再有条件对象,一个锁可以生成很多歌条件对象,当不满足条件对象时,线程挂起,直到另外的线程在相同的条件对象上唤醒。那么阻塞的线程则进入等待集
内部对象锁
嵌入到java语言内部机制,受保护的方法必须获得内部对象锁(一个对象只有一个内部对象锁),它只有一个相关条件 wait()方法把线程放入等待集,线程阻塞,notifyAll notify方法解除线程阻塞,
另外如果将静态方法声明Synchronized也是合法的,如果要进入这个方法,则要获得类对象锁,(上一个是对象锁,是类一个实例的锁)
建议最好不使用Lock/Condition 也不使用内部对象锁,很多情况下使用java.util.concurrent包中的一种机制。
获得内部对象锁有一种方式,进入Synchronized同步块,一种是:同步阻塞 Synchronized(object)
若是Synchronized(object.class)
则是获得类对象锁。
以上是java线程底层的机制,新手不建议使用,可以使用java.util.concurrent包中的提供的线程安全的集合替代。
如 BlockingDeque 这样的线程阻塞队列是现成安全的。(如在银行例子中 有很线程生成修改指令作为生产者 放入队列,而只有一个线程作为消费者去修改银行对象,来实现线程安全。如 在一个搜索的例子中,一个线程负责向队列中放入一个目录下的所有文件,另外很多线程作为消费者去从队列中取得文件并在文件中查找关键字)
另外如果想让普通的队列实现线程安全可以使用,
Collections.synchronizedList(list)
Collections.synchronizedMap(m)
来获得线程安全的集合,它们的实现是对操作使用了synchronized关键字,而上面的java.util.concurrent中的线程安全的集合是使用的复杂的算法来实现线程的安全。所以java.util.concurrent 中的集合相对效率高点。