Java实现同步与互斥
来源:互联网 发布:ftpflashfxp mac 编辑:程序博客网 时间:2024/06/03 19:24
synchronized----实现互斥
wait,notify-----实现同步
synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。
wait()/notify():调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放。而调用 任意对象的notify()方法则导致因调用该对象的 wait() 方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。
wait()/notify():调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放。而调用 任意对象的notify()方法则导致因调用该对象的 wait() 方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。
synchronized和wait()、notify()的关系
1.有synchronized的地方不一定有wait,notify
2.有wait,notify的地方必有synchronized.这是因为wait和notify不是属于线程类,而是每一个对象都具有的方法,而且,这两个方法都和对象锁有关,有锁的地方,必有synchronized。
另外,请注意一点:如果要把notify和wait方法放在一起用的话,必须先调用notify后调用wait,因为如果调用完wait,该线程就已经不是current thread了,因为wait会释放对象锁。
注:调用wait()方法前的判断最好用while,而不用if;while可以实现被wakeup后thread再次作条件判断;而if则只能判断一次。
一、synchronized作函数修饰符
public synchronized void fun()
{
……..
}
fun()就是一个同步方法,此时synchronized关键字锁定的是调用这个同步方法的对象。假设有p1和p2是同一个类的两个对象,p1在不同的线程中运行会对fun()产生互斥和同步的效果;但是p2对象和p1对象互相不会对fun()产生同步和互斥作用(当然,不同线程中的p2对象的fun()还是有同步和互斥)。{
……..
}
对于非static的情况,synchronized是对象级别的,其实质是将synchronized作用于对象引用(object reference)上,即拿到p1对象锁的线程,对p1的fun()方法有同步互斥作用,不同的对象之间坚持“和平共处”。
二、synchronized同步程序块
public void fun_1(someObject obj)
{
synchronized(obj)
{
……
}
}
{
synchronized(obj)
{
……
}
}
上面代码中,锁住的是obj对象(正如前面说的,对于非static的情况,sysnchronized是对象级别的),谁拿到这个锁,谁就可运行obj控制的那段代码。通常情况,如果我们知道对用哪个对象作为锁时,就可以像上面的代码块一样使用synchronized。假如没有明确的对象作为锁,程序员又希望同步一段代码块,就可以使用下面的trick。
class Test implements Runnable
{
private byte[] lock = new byte[0]; // 定一个instance变量
public void fun_2()
{
synchronized(lock)
{
……
}
}
}
{
private byte[] lock = new byte[0]; // 定一个instance变量
public void fun_2()
{
synchronized(lock)
{
……
}
}
}
在上面的代码示例中,定义了一个特殊的instance变量作为锁,这个instance变量必须是一个对象。定义lock为长度为0的数组对象是最佳方案。在编译后的字节码中,生成长度为0的byte[]只需要三条操作码。假如我们用所有类的超类Object来作锁,需要生成七条操作码。
[注意:]如果需要定义特殊的instance变量作为锁,最好将其定义为private的,同时定义其get()方法(如果使用自己定义的类的对象作为锁)。如果变量是public的,其他类的对象可以得到这个锁的控制权,并修改这个锁。这是非常不安全的。
三、synchronized修饰static方法
synchronized静态(static)方法的用法如下面代码示例:
public static synchronized void fun_3()
{
……
}
{
……
}
如果方法用static修饰,synchronized的作用范围就是class一级的,它对类的所有对象起作用。像第一点中的fun()方法,如果是static的,那么synchronized对p1对象和p2对象都起到同步互斥的作用。
最后简单总结一下:
(1) 通常把synchronized关键字的作用范围划分为类的范围和对象的范围两种。
(2) synchronized关键字是不能继承的,即,父类的synchronized方法在子类中不是synchronized,必须要重新的显式的声明为synchronized才行。
(3) 实现同步需要很大的系统开销,导致延迟等待,甚至可能造成死锁,所以在非多线程情况下不要使用。
0 0
- Java实现同步与互斥
- 互斥与同步实现函数
- java实现同步互斥问题
- java 线程同步与互斥
- 【Java】线程并发、互斥与同步
- Java——同步与互斥
- JAVA线程的同步与互斥
- Java多线程-----互斥与同步
- java线程同步与互斥
- 互斥与同步
- 互斥与同步
- 互斥与同步
- 互斥与同步
- 互斥与同步
- 互斥与同步
- 同步与互斥
- 同步与互斥
- 同步与互斥
- 好风凭借力,微信产业链上“三大势力”已形成
- COM组件开发知识重点
- union all 支持排序吗
- hibernate-4.3.5 与Spring(Spring MVC4.0.4)注解方式集成
- SBL-SMI-00046: The port %1 is already in use
- Java实现同步与互斥
- eclipse SWT 界面屏幕中央位置
- 获取图片的长和宽
- 北大青鸟ASP.NET之总结篇
- Win7 系统上安装SQL Server 2008一步一步图解教程(转载)
- Eclipse maven svn整合
- MySQL技术内幕InnoDB存储引擎 第四章 表
- SAP中的一些FUNCTION应用
- win7 64位系统+vs2010 编译安装openssl