java并发synchronized的原理和应用
欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/jsh/2019/0930/116269.html
java并发编程这个领域中synchronized关键字一直都是元老级的角色,在java早期版本中,synchronized属于重量级锁,效率低下,因为监视器锁(monitor)是依赖于底层的操作系统的Mutex Lock来实现的,java的线程是映射到操作系统的原生线程之上的
如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高
在JDK1.6之后java官方对从JVM层面对synchronized 较大优化,所以现在的synchronized锁效率也优化得很不错
JDK1.6对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销
synchronized实现原理
通过反编译下面的代码来看看Synchronized是如何实现对代码块进行同步的,切换到类的对应目录执行javac SynchronizedTest.java命令生成编译后的.class文件,然后执行javap -v SynchronizedTest.class
1)synchronized同步代码块
public class SynchronizedTest { public static void main(String[] args) { new SynchronizedTest().method(); } public void method() { synchronized (this) { System.out.println("synchronized 代码块"); } }}
3)脏读
多个线程访问的是同一个对象,哪个线程先执行带synchronized关键字的方法,则哪个线程就持有该方法,那么其他线程只能呈等待状态
如果多个线程访问的是多个对象则不一定,因为多个对象会产生多个锁
发生脏读的情况实在读取实例变量时,此值已经被其他线程更改过public class PublicVar { public String username = "A"; public String password = "AA"; synchronized public void setValue(String username, String password) { try { this.username = username; Thread.sleep(3000); this.password = password; System.out.println("setValue method thread name=" + Thread.currentThread().getName() + " username=" + username + " password=" + password); } catch (InterruptedException e) { e.printStackTrace(); } } //该方法前加上synchronized关键字就同步了 public void getValue() { System.out.println("getValue method thread name=" + Thread.currentThread().getName() + " username=" + username + " password=" + password); } public static void main(String[] args) { try { PublicVar publicVarRef = new PublicVar(); ThreadC thread = new ThreadC(publicVarRef); thread.start(); Thread.sleep(500);//打印结果受此值大小影响 publicVarRef.getValue(); } catch (InterruptedException e) { e.printStackTrace(); } } static class ThreadC extends Thread { private PublicVar publicVar; public ThreadC(PublicVar publicVar) { this.publicVar = publicVar; } @Override public void run() { publicVar.setValue("B", "BB"); } }}
相关文章