synchronized

JAVA【Volidate与锁机制】

怎甘沉沦 提交于 2019-12-03 22:24:52
Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized ”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形。 锁提供了两种主要特性: 互斥(mutual exclusion) 和 可见性(visibility) 。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。 Volatile 变量 Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。因此,单独使用 volatile 还不足以实现计数器

why using volatile with synchronized block?

匆匆过客 提交于 2019-12-03 22:02:50
I saw some examples in java where they do synchronization on a block of code to change some variable while that variable was declared volatile originally .. I saw that in an example of singleton class where they declared the unique instance as volatile and they sychronized the block that initializes that instance ... My question is why we declare it volatile while we synch on it, why we need to do both?? isn't one of them is sufficient for the other ?? public class someClass { volatile static uniqueInstance = null; public static someClass getInstance() { if(uniqueInstance == null) {

Should I synchronize listener notifications, or not?

你说的曾经没有我的故事 提交于 2019-12-03 20:20:33
I am always very hesitant to bring my locks in the open, to make them public. I always try to keep the locks restricted to my implementation. Not doing that, is a recipe for deadlocks, I believe. I have the following class: class SomeClass { protected ArrayList<Listener> mListeners = new ArrayList<Listener>(); protected void addListener(Listener listener) { synchronized (mListeners) { mListeners.add(listener); } } protected void removeListener(Listener listener) { synchronized (mListeners) { mListeners.remove(listener); } } ... } When SomeClass wants to notify his listeners, would you do:

自旋锁、阻塞锁、重入锁、偏向锁、轻量锁和重量锁

笑着哭i 提交于 2019-12-03 20:16:37
1、自旋锁: 采用让当前线程不停的在循环体内执行实现,当循环的条件被其它线程改变时才能进入临界区 举例如下: 优缺点分析: 由于自旋锁只是将当前线程不停地执行循环体,不进行线程状态的改变,所以响应速度更快。但当线程数不停增加时,性能下降明显,因为每个线程都需要执行,占用CPU时间。如果线程竞争不激烈,并且保持锁的时间段。适合使用自旋锁。 大家可以点击加群【JAVA架构知识学习讨论群】473984645,(如多你想跳槽换工作,但是技术又不够,或者工作遇到了瓶颈,我这里有一个Java的免费直播课程,讲的是高端的知识点,只要有1-5年的开发工作经验可以加群找我要课堂链接。)注意:是免费的 没有开发经验的误入。 2、阻塞锁 : 阻塞锁改变了线程的运行状态,让线程进入阻塞状态进行等待,当获得相应的信号(唤醒或者时间)时,才可以进入线程的准备就绪状态,转为就绪状态的所有线程,通过竞争,进入运行状态。 优缺点分析: 阻塞锁的优势在于,阻塞的线程不会占用cpu时间,不会导致 CPu占用率过高,但进入时间以及恢复时间都要比自旋锁略慢。在竞争激烈的情况下 阻塞锁的性能要明显高于自旋锁。 3、重入锁 : Java中的synchronized同步块是可重入的。这意味着如果一个java线程进入了代码中的synchronized同步块,并因此获得了该同步块使用的同步对象对应的管程上的锁

Thread.sleep() with synchronization in java

拟墨画扇 提交于 2019-12-03 20:10:48
when Thread.sleep(10000) is invoked current Thread will go to sleeping state. If Thread.sleep(10000) is invoked in synchronization method whether other thread can execute in that period? If you do Thread.sleep(10000) within a synchronized method or block you do not release the lock. Hence if other Threads are waiting on that lock they won't be able to execute. If you want to wait for a specified amount of time for a condition to happen and release the object lock you need to use Object.wait(long) private synchronized void deduct() { System.out.println(Thread.currentThread().getName()+ " Before

深入分析Synchronized原理

一曲冷凌霜 提交于 2019-12-03 20:06:27
前言 记得开始学习Java的时候,一遇到多线程情况就使用synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决多线程情况的百试不爽的良药。但是, 随着学习的进行我们知道在JDK1.5之前synchronized是一个重量级锁,相对于j.u.c.Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它 。 不过, 随着Javs SE 1.6对synchronized进行的各种优化后,synchronized并不会显得那么重了 。下面来一起探索synchronized的基本使用、实现机制、Java是如何对它进行了优化、锁优化机制、锁的存储结构等升级过程。 大家可以点击加群【JAVA架构知识学习讨论群】 473984645, (如多你想跳槽换工作,但是技术又不够,或者工作遇到了瓶颈,我这里有一个Java的免费直播课程,讲的是高端的知识点,只要有1-5年的开发工作经验可以加群找我要课堂链接。)注意:是免费的 没有开发经验的误入。 1 基本使用 Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。 Synchronized的作用主要有三个 : 原子性 :确保线程互斥的访问同步代码; 可见性 :保证共享变量的修改能够及时可见

Java AtomicInteger的用法

爱⌒轻易说出口 提交于 2019-12-03 18:40:41
1.java.util.concurrent.atomic 的包里有AtomicBoolean, AtomicInteger,AtomicLong,AtomicLongArray, AtomicReference等原子类的类,主要用于在高并发环境下的高效程序处理,来帮助我们简化同步处理. 在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。 2.AtomicInteger的基本方法 创建一个AtomicInteger AtomicInteger atomicInteger = new AtomicInteger(123); System.out.println(atomicInteger.get()); --->输出 : 123 创建一个不传值的,默认值为0 AtomicInteger atomicInteger = new AtomicInteger(); System.out.println(atomicInteger.get()); ---->输出: 0 获取和赋值 atomicInteger.get(); //获取当前值 atomicInteger.set(999); //设置当前值 atomicInteger.compareAndSet

Java内存模型相关原则详解

假如想象 提交于 2019-12-03 17:13:30
在《 Java内存模型(JMM)详解 》一文中我们已经讲到了Java内存模型的基本结构以及相关操作和规则。而Java内存模型又是围绕着在并发过程中如何处理原子性、可见性以及有序性这三个特征来构建的。本篇文章就带大家了解一下相关概念、原则等内容。 原子性 原子性即一个操作或一系列是不可中断的。即使是在多个线程的情况下,操作一旦开始,就不会被其他线程干扰。 比如,对于一个静态变量int x两条线程同时对其赋值,线程A赋值为1,而线程B赋值为2,不管线程如何运行,最终x的值要么是1,要么是2,线程A和线程B间的操作是没有干扰的,这就是原子性操作,不可被中断的。 Java内存模型对以下操作保证其原子性:read,load,assign,use,store,write。我们可以大致认为基本数据类型的访问读写是具备原子性的(前面也提到了long和double类型的“半个变量”情况,不过几乎不会发生)。 从Java内存模型底层来看有上面的原子性操作,但针对用户来说,也就是我们编写Java的程序,如果需要更大范围的原子性保障,就需要同步关键字——synchronized来保障了。也就是说synchronized中的操作也具有原子性。 可见性 可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。 Java内存模型是通过变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值

面试必问的Synchronized知道这些就可以了

[亡魂溺海] 提交于 2019-12-03 16:42:52
Synchronized关键字算是Java的元老级锁了,一开始它撑起了Java的同步任务,其用法简单粗暴容易上手。但是有些与它相关的知识点还是需要我们开发者去深入掌握的。比如,我们都知道通过Synchronized锁来实现互斥功能,可以用在方法或者代码块上,那么不同用法都是怎么实现的,以及都经历了了哪些优化等等问题都需要我们扎实的理解。 1.基本用法 2.实现原理 2.1 同步代码块的实现 2.2 同步方法的实现 3.锁升级 3.1 Java对象头介绍 3.2 什么是锁升级 1.基本用法 通常我们可以把Synchronized用在一个方法或者代码块里,方法又有普通方法或者静态方法。 对于普通同步方法,锁是当前实例对象,也就是this public class TestSyn{ private int i=0; public synchronized void incr(){ i++; } } 对于静态同步方法,锁是Class对象 public class TestSyn{ private static int i=0; public static synchronized void incr(){ i++; } } 对于同步代码块,锁是同步代码块里的对象 public class TestSyn{ private int i=0; Object o = new Object();

synchronized 持有的锁分析?是对象的锁还是类的锁?

空扰寡人 提交于 2019-12-03 16:03:25
1. synchronized 关键字是用来控制多线程同步时候使用的一种方式,在多线程的状态下,控制synchronized代码段不被多个线程同时执行。可以加在一段代码上,也可以加在方法上。 2.synchronized实现的锁机制是一种不公平的锁,在某种意义上,可能导致某些线程的饥饿,但相比于公平锁能提高吞吐率。 3. 不要认为随意的给方法或者代码块上面加上synchronized就可以实现锁 请看下面的代码 class Sync { public synchronized void test() { System.out.println("test开始.."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("test结束.."); } } class MyThread extends Thread { public void run() { Sync sync = new Sync(); sync.test(); } } public class Main { public static void main(String[] args) { for (int i = 0; i < 3; i++) { Thread