今天我简单谈谈Java的两个同步锁。 同步和返回锁定。
java先生一定很熟悉synchronized这个关键词。 通常用于处理同步问题。
首先,让我们看一下同步的常见用法。
如何使用即时方法限定类的静态方法限定代码块查看以下三种方法的简单实现代码
实例方法公共类测试{
私有安装=0;
publicsynchronizedvoidaddNum (
sum=sum 1;
}
}
当限定实例方法时,锁定对象是当前类的实例,不同的实例对象不会产生互斥效果。
类的静态方法公共类测试{
privatestaticintnum1=0;
publicstaticsynchronizedvoidaddsum (
num1=num1 1;
}
}
修改静态方法时,锁定对象是当前类Class对象,可以在不使用线程中的不同实例的情况下获得互斥效果。
代码块公共类测试{
privateObjectlock=newObject (;
publicvoidaddSum (
同步(lock ) {
for(inti=0; i10; I ) {
System.out.println;
}
}
}
}
在限定代码块时,锁定对象是synchronized后面括号中的对象,任何对象都可以用作锁定对象。
接下来,我们来看看ReentrantLock的使用方法
公共类测试{
reentrantlocklock=newreentrantlock;
publicstaticvoidmain (string [ ] args ) {
Testtt=newTest (;
threadT1=newthread(newrunnable () {
@Override
公共语音运行(}
tt.add (;
}
);
threadT2=newthread(newrunnable () {
@Override
公共语音运行(}
tt.add (;
}
);
t1.start (;
t2.start (;
}
公共语音添加
try{
lock.lock (;
for(inti=0; i10; I ) {
System.out.println ('测试' I );
}
}catch(exceptione ) }
法利{
lock.unlock (;
}
}
}
从以上代码中可以看出,与已同步不同,ReentrantLock必须手动锁定和解锁代码。
在上面的代码中,finally方法调用unlock解锁方法是因为发生异常时synchronized会自动解锁,而ReentrantLokc不会自动解锁,因此finall
公平锁和非公平锁公平锁:通过同步队列,允许多个线程按申请锁的顺序获取锁。
缺省情况下,synchronized和ReentrantLock都是异步锁。 但是,通过构造函数将ReentrantLock传递给true可以建立公平的锁,并可以利用以下源代码的一部分。
两者的不同1 .锁定的安装synchronized是JVM虚拟机的安装,ReentrantLock是JDK的安装,是java.util.concurrent软件包内的锁定。
2 .性能新版本的java对同步进行了许多优化,引入了偏转锁定、轻锁定、自旋锁定等多个概念,两者性能基本相同。
3 .费尔洛克在上面的文章中已经提到过,这里省略。
4 .并非所有JDK版本都支持选择返回锁定。 除非需要使用reentrantlock的高级功能,否则优先使用同步。 这是一种在JVM中内置和实现的锁定机制,本机支持,因此您不必担心不释放锁定导致的死锁问题。 因为JVM会确保锁的释放。
实现一个例子的双重检查锁(需要面试) (publicclassSingleton{ ) )。
privateSingleton () }
通过使用volatile限定变量,可以禁止JVM指令的排序,并允许多线程唯一地获取实例。
privatevolatilestaticsingletoninstance
publicstaticsingletongetinstance (
if (实例==null ) {
synchronized(Singleton.class ) {
if (实例==null ) {
instance=newSingleton (;
}
}
}
返回实例;
}
}
synchronized基础的实现原理synchronized是使用对象内部监视器(ObjectMonitor )的同步机制,基于基于JVM的OS基础的Mutex Lock )来实现,其间从用户状态到OS synchronized实现锁是一种重量锁,当多个线程在上下文之间切换时,它是一种非常沉重的操作,而且成本非常高。