synchronized的用法

来源:互联网 发布:广东深圳淘宝地址大全 编辑:程序博客网 时间:2024/04/30 05:51

1、synchronized关键字的作用域有二种:
1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

 

2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;

3、synchronized关键字不能继承。基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;

 

notify()和wait()说明:

这两个方法属于最底层的object基础类的,每个对象都有notify和wait的功能,他们是用来操纵锁的,。

每个对象都有锁,锁是每个对象的基础,既然锁是基础的,那么操纵锁的方法当然也是最基础了。

 

Thinking in Java中的解释:

“wait()允许我们将线程置入"睡眠"状态,同时又"积极"地等待条件发生改变.

而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变。”

 

wait()允许我们将线程置入"睡眠"状态",也就是说,wait也是让当前线程阻塞的,这一点和sleep或者suspend是相同的。

但区别在于,"(wait)同时又"积极"地等待条件发生改变",这一点很关键,sleep和suspend无法做到。

我们有时候需要通过同步 (synchronized)的帮助来防止线程之间的冲突,而一旦使用同步,就要锁定对象,也就是获取对象锁。

其它要使用该对象锁的线程都只能排队等着, 等到同步方法或者同步块里的程序全部运行完才有机会。

在同步方法和同步块中,无论sleep()还是suspend()都不可能自己被调用的时候解除锁定,他们都霸占着正在使用的对象锁不放。
而wait却可以让同步方法或者同步块暂时放弃对象锁,而将它暂时让给其它需要对象锁的人(这里应该是程序块,或线程)用。

这意味着可在执行wait()期间调用线程对象中的其他同步方法!在其它情况下(sleep、suspend),这是不可能的。


由于只是暂时放弃对象锁,暂时给其它线程使用,wait所在的线程还是要把对象锁收回来。

那怎么把对象锁收回来呢?
1.限定借出去的时间.在wait()中设置参数,比如wait(1000),以毫秒为单位;

2.让借用者通知我,用完了就归还;


我们可将一个wait()和notify()置入任何同步方法或同步块内部,无论在那个类里是否准备进行涉及线程的处理。

实际上,我们也只能在同步方法或者同步块里面调用wait()和notify()。

synchronized (b){...};的意思是定义一个同步块,使用b作为资源锁。b.wait();的意思是临时释放锁,并阻塞当前线程,好让其他使用同一把锁的线程有机 会执行,在这里要用同一把锁的就是b线程本身.这个线程在执行到一定地方后用notify()通知wait的线程,锁已经用完,待notify()所在的 同步块运行完之后,wait所在的线程就可以继续执行。

 

 

原创粉丝点击