synchronized

java高并发系列 - 第12天JUC:ReentrantLock重入锁

喜欢而已 提交于 2019-12-09 10:56:43
java高并发系列 - 第12天JUC:ReentrantLock重入锁 本篇文章开始将juc中常用的一些类,估计会有十来篇。 synchronized的局限性 synchronized是java内置的关键字,它提供了一种独占的加锁方式。synchronized的获取和释放锁由jvm实现,用户不需要显示的释放锁,非常方便,然而synchronized也有一定的局限性,例如: 当线程尝试获取锁的时候,如果获取不到锁会一直阻塞,这个阻塞的过程,用户无法控制 如果获取锁的线程进入休眠或者阻塞,除非当前线程异常,否则其他线程尝试获取锁必须一直等待 JDK1.5之后发布,加入了Doug Lea实现的java.util.concurrent包。包内提供了Lock类,用来提供更多扩展的加锁功能。Lock弥补了synchronized的局限,提供了更加细粒度的加锁功能。 ReentrantLock ReentrantLock是Lock的默认实现,在聊ReentranLock之前,我们需要先弄清楚一些概念: 可重入锁:可重入锁是指同一个线程可以多次获得同一把锁;ReentrantLock和关键字Synchronized都是可重入锁 可中断锁:可中断锁时只线程在获取锁的过程中,是否可以相应线程中断操作。synchronized是不可中断的,ReentrantLock是可中断的 公平锁和非公平锁

并发编程(四)显示锁

对着背影说爱祢 提交于 2019-12-09 10:55:39
1.显示锁 Java程序可以依靠synchronized关键字隐式的获取锁实现锁功能,但是它将锁的获取和释放固话了,也就是先获取再释放。 (synchronized是语言的特性(内置锁),Lock是一个类 使用的时候需要对其实例化 和方法调用,内存,CPU消耗较大。且JDK中对synchonized的优化已经做的很好,一般情况下没有特殊需求 尽量使用synchonized) 显示锁特性: 1)尝试非阻塞的获取锁:当前线程尝试获取锁,如果这一时刻锁没有被其他线程获取,则成功获取并持有锁; 2)能被中断的获取锁:与synchronized不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。 3)超时获取锁:在指定的截止时间之前获取锁,如果截止时间到了仍然无法获取到锁,则返回 使用范式: lock.lock();try { num--;} finally { lock.unlock();} 在finally块中释放锁,目的是保证在获取到锁之后,最终能够释放。不要将获取锁的过程写在try中,因为 如果在获取锁(自定义锁的实现)时发生了异常,异常抛出时,也会导致锁无故释放常用API public class UseLock { private Lock lock = new ReentrantLock(); private int num =

java的synchronized可重入锁

风格不统一 提交于 2019-12-09 10:55:14
在java内部 ,同一线程在调用自己类中其他synchronized方法/块或调用父类的synchronized方法/块都不会阻碍该线程的执行,就是说同一线程对同一个对象锁是可重入的 ,而且同一个线程可以获取同一把锁多次,也就是可以多次重入。 因为java线程是基于“每线程(per-thread)”,而不是基于“每调用(per-invocation)”的(java中线程获得对象锁的操作是以每线程为粒度的,per-invocation互斥体获得对象锁的操作是以每调用作为粒度的) 我们再来看看重入锁是怎么实现可重入性的,其实现方法是为每个锁关联一个线程持有者和计数器,当计数器为0时表示该锁没有被任何线程持有,那么任何线程都可能获得该锁而调用相应的方法;当某一线程请求成功后,JVM会记下锁的持有线程,并且将计数器置为1;此时其它线程请求该锁,则必须等待;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增;当线程退出同步代码块时,计数器会递减,如果计数器为0,则释放该锁。 synchronized是隐式锁,位于concurrent.locks保重的Reentranrlock是显示锁,注意需要手动的unlock解锁 来源: https://www.cnblogs.com/phpzhou/p/6547067.html

Volatile or synchronized for primitive type?

ⅰ亾dé卋堺 提交于 2019-12-09 04:19:57
问题 In Java, assignment is atomic if the size of the variable is less than or equal to 32 bits but is not if more than 32 bits. What (volatile/synchronized) would be more efficient to use in case of double or long assignment? Like, volatile double x = y; synchronized is not applicable with primitive argument. How do I use synchronized in this case? Of course I don't want to lock my class, so this should not be used. 回答1: If you find locking on the object itself too heavy, then synchronized is the

Does a ConcurrentHashMap need to be wrapped in a synchronized block?

折月煮酒 提交于 2019-12-08 22:48:13
问题 Do all non-retreival operations on a ConcurrentHashMap ( put() , remove() etc.) need to be wrapped in a synchronized(this) block? I understand that all of these operations are thread-safe, so is there any real benefit/need in doing so? The only operations used are put() and remove() . protected final Map<String, String> mapDataStore = new ConcurrentHashMap<String, String>(); public void updateDataStore(final String key, final String value) { ... synchronized (this) { mapDataStore.put(key,

三个线程交替顺序打印ABC

孤街浪徒 提交于 2019-12-08 20:29:29
首先看下问题: 建立三个线程A、B、C,A线程打印10次字母A,B线程打印10次字母B,C线程打印10次字母C,但是要求三个线程同时运行,并且实现交替打印,即按照ABCABCABC的顺序打印。 这是一个非常有意思的问题。本质上我们要让并发运行的三个线程能够感知其他线程的行为,进而控制自己的行为,达到整体有序。 这也是一个线程通信问题,怎么解决呢? 最简单的方案就是共享内存中放几把锁,运行中的线程只需要通过 竞争锁 这个行为就能感知其他线程。 有很多种方法实现 使用synchronized, wait和notifyAll 使用Lock->ReentrantLock 和 state标志 使用Lock->ReentrantLock 和Condition(await 、signal、signalAll) 使用Semaphore 使用AtomicInteger 详细可以参考 https://blog.csdn.net/hefenglian/article/details/82596072 我们看到很多实现中都是多个线程去执行同一个执行体,公共的执行体里面来进行锁的判断、序号的判断等等, 其实这些并不是必须的,接下来我们展示一个两个线程顺序打印AB的实例, 三个也是类似处理,就不写了。 package thread; /** * @version jdk12 */ public class

案例分析:设计模式与代码的结构特性

天大地大妈咪最大 提交于 2019-12-08 20:22:27
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 单例模式定义    单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,"阻止"所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。 单例模式的动机   对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态

复习八(多线程)

与世无争的帅哥 提交于 2019-12-08 16:23:25
1.进程:进程是应用程序执行的实例,进程有独立的内存空间和系统资源 2.线程:线程是cpu调度和分配的基本单位,线程是进程中执行运算的最小单位,可以完成一个独立的顺序控制流程 一个进程中同时运行了多个线程用来完成不同的工作称之为 多线程 多线程是交替占用cpu资源而并非真正的一起执行 多线程优点:     1.充分利用CPU资源     2.简化编程模型     3.带来良好的用户体验 java提供了java.long.Thread类支持线程编程 主线程:main()方法为主线程入口,产生其他子线程的线程必须最后完成执行因为他执行各种关闭操作 获取主线程对象:   Thread thread=Thread.currentThread(); 创建线程:     1.继承Thread类       1.定义一个类继承Thread       2.重写run方法       3.使用start()方法启动线程     2.实现Runnable接口       Threa thread=new Thread(实现接口的类名);       thread.start(); 继承Thread 类编写简单可以直接操作线程适用于单线程 实现Runnable类 避免了单继承的局限性便于共享资源 线程调度:按照特定的机制为多个线程分配cpu资源的使用权 线程方法:     .setPriority

Mutual exclusion - How synchronized works? [closed]

孤者浪人 提交于 2019-12-08 14:21:45
问题 Closed . This question needs details or clarity. It is not currently accepting answers. Want to improve this question? Add details and clarify the problem by editing this post. Closed last year . As mentioned in answer, synchronized is implemented using compareAndSwap , which is non-blocking algorithm. On synchronized without using wait() , Does a thread state set to BLOCKED ? Does a thread in BLOCKED & WAITING state consume CPU cycles? 回答1: As mentioned in answer, synchronized is implemented

Simplification of synchronized block in Java

谁说我不能喝 提交于 2019-12-08 13:09:16
问题 I'm having some trouble wrapping my head around the concept of synchronized blocks in Java. I feel I have understood synchronized methods well enough. So I thought of an analogy to help me understand synchronized blocks in terms of synchronized methods. Please let me know if this equivalence that I have proposed is correct. Also, I have only mentioned this for a non-static synchronized block for now. However, points on static synchronzied blocks are also welcome. public void method() { //code