上一讲内容中,我们讲到了synchronized的两种使用方法,以及它们之间的区别,其实synchronized的使用功能其实是存在问题的,比如说有一个很复杂的耗时的操作,而且它涉及到一个并发性的问题,所以只能使用synchronized关键字让每次一个线程去访问,此时如果有一个线程进入操作,耗时了很长时间,而其他的线程都在等待,这样就会导致等待队列中的越后面的线程等待时间越长,这对用户来说显然是一种很不好的情况,这种情况一般在JDK1.4之前是没办法处理的,只能让其等待,在JDK1.5之后就出现了同步包的机制,在这种情况下,我们必须对其进行处理,比如说在等待的线程中当等待某一个时间段之后会返回一个数值,表示超时,建议重新发送消息。
并发处理的类或者接口主要是在 Package java.util.concurrent下
Utility classes commonly useful in concurrent programming.[这是一些辅助类通常用于并发编程,就是多线程编程,接下去会找个时间去讲解一下,它比较有细粒度的解决以上问题。]
1. 怎样实现多线程同步
1) 当synchronized方法执行完或发生异常时,会自动释放锁。
2)被synchronized保护的数据应该是私有(private)的。[这样外面就不会去访问到里面的数据了]
3) 引入了同步锁之后同步的线程状态如下图所示:
Running--> Blocked in object's lock pool : 此时synchronized方法的对象被锁住了,所以其他线程进入这个对象锁池中。
Blocked in object's lock pool --> Runnable: 对象被解锁了,此时线程获得到锁进入到可运行状态等待CPU调度。
2. 线程间的相互作用[重要]:
我们知道一旦线程起来之后是没法控制它的,对于线程访问synchronized方法,他们仅仅是两个线程对这种目标方法访问之间的协调而已,两个线程之间并没有进行通信,比如说线程一执行完成之后通知线程二,线程二完成之后再通知其他线程。类似例子建议学习操作系统中的生产者消费者问题,还有哲学家就餐问题。
线程之间处理不当,很容易引起 死锁(deadlock)
1)wait and notify
2)The pools:
(1)Wait pool
(2) Lock pool
3. 针对上述问题,我们来剖析一下Object类中一些方法的使用。注意Object类中的方法都很重要。