synchronized

线程安全问题总结!

[亡魂溺海] 提交于 2019-12-02 15:11:20
转载内容: https://mp.weixin.qq.com/s/s5eVZhkPoJIrH3zy65CwZg 仅用于个人学习,如有侵权私信立删! 什么是进程 电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互独立存在的。比如下图中的QQ、酷狗播放器、电脑管家等等。 什么是线程 进程想要执行任务就需要依赖线程。换句话说,就是进程中的最小执行单位就是线程,并且一个进程中至少有一个线程。 那什么是多线程?提到多线程这里要说两个概念,就是串行和并行,搞清楚这个,我们才能更好地理解多线程。 所谓串行,其实是相对于单条线程来执行多个任务来说的,我们就拿下载文件来举个例子:当我们下载多个文件时,在串行中它是按照一定的顺序去进行下载的,也就是说,必须等下载完A之后才能开始下载B,它们在时间上是不可能发生重叠的。 并行:下载多个文件,开启多条线程,多个文件同时进行下载,这里是严格意义上的,在同一时刻发生的,并行在时间上是重叠的。 了解了这两个概念之后,我们再来说说什么是多线程。举个例子,我们打开腾讯管家,腾讯管家本身就是一个程序,也就是说它就是一个进程,它里面有很多的功能,我们可以看下图,能查杀病毒、清理垃圾、电脑加速等众多功能。 按照单线程来说,无论你想要清理垃圾、还是要病毒查杀,那么你必须先做完其中的一件事,才能做下一件事,这里面是有一个执行顺序的。 如果是多线程的话

Synchronized 与Lock的不同之处

丶灬走出姿态 提交于 2019-12-02 15:09:55
Synchronized 与Lock的不同之处 用法不一样。synchronized既可以加在方法上,也可以加载特定的代码块上,括号中表示需要锁的对象。而Lock需要显示地指定起始位置和终止位置。synchronzied是托管给jvm执行的,Lock锁定是通过代码实现的。 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。 锁的机制不一样。synchronized获得锁和释放的方式都是在块结构中,而且是自动释放锁。而Lock则需要开发人员手动去释放,并且必须在finally块中释放,否则会引起死锁问题的发生。 Lock是一个接口,不是Java语言内置的;synchronized是Java语言的关键字,因此是内置特性。 采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后或者出现异常时,系统会自动让线程释放对锁的占用;而Lock在发生异常时,如果没有主动通unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁; Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时

Java基础(二十六) 线程同步中synchronized用法

旧城冷巷雨未停 提交于 2019-12-02 14:53:24
一、synchronized概述 synchronized是Java中的关键字,synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性,Java中每一个对象都可以作为锁,这是synchronized实现同步的基础。 它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象; 2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象; 3. 修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象; 4. 修饰一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。 二、修饰一个代码块 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象。 1、多个线程访问 同一对象 的同步代码块 一个线程访问 同一个对象 中的synchronized(this)同步代码块时,其它线程试图访问该对象的线程将被阻塞。 public class ThreadSync implements Runnable{ private volatile static int

JAVA中多线程的死锁

我只是一个虾纸丫 提交于 2019-12-02 14:52:13
例子: class Test implements Runnable { private boolean flag ; Test ( boolean flag ) { this . flag = flag ; } public void run ( ) { if ( flag ) { synchronized ( MyLock . locka ) { System . out . println ( "if.....locka...." ) ; synchronized ( MyLock . lockb ) { System . out . println ( "if.....lockb...." ) ; } } } else { synchronized ( MyLock . lockb ) { System . out . println ( "else.....lockb...." ) ; synchronized ( MyLock . locka ) { System . out . println ( "else.....locka...." ) ; } } } } } class MyLock { public static final Object locka = new Object ( ) ; public static final Object lockb =

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

♀尐吖头ヾ 提交于 2019-12-02 14:41:07
摘自: https://www.cnblogs.com/wyc1994666/p/11748212.html 面试必问的Synchronized知道这些就可以了 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++; } }

Why is Java synchronized not working as expected?

久未见 提交于 2019-12-02 14:08:23
问题 I'm trying to figure out how synchronized methods work. From my understanding I created two threads T1 and T2 that will call the same method addNew , since the method is synchronized shouldn't it execute all the iterations of the for loop for one thread and then the other? The output keeps varying, sometimes it prints it right, other times it prints values from T1 mixed with T2 values. The code is very simple, can someone point out what am I doing wrong? Thank you. public class Main { public

多线程性能分析

青春壹個敷衍的年華 提交于 2019-12-02 12:19:42
如果越多的资源被消耗在锁的管理和调度上,那么应用程序得到的资源就越少。 锁的实现方式越好,将需要越少的系统调用和上下文切换,并且在共享内存总线上的内存同步通讯量越少。 线程引入的开销 上下文切换: 线程调度需要访问由操作系统和JVM共享的数据结构。 如果新的线程被切换进来,所需要的数据不在当前处理器的本地缓存中, 上下文切换将导致一些缓存缺失,因而线程在首次调度运行时会更加缓慢。 频繁的IO操作(阻塞)将增加线程的上下文切换。 内存同步: synchronized 和 volatile 提供的可见性保证中可能会使用一些特殊指令,即内存栅栏。 内存栅栏可以刷新缓存,抑制指令重排。 非公平锁性能高于公平锁 恢复一个被挂起的线程与该线程真正开始运行存在者严重的延迟。 非公平锁允许插队,可以避免这种延迟。 如果锁的持有时间较长,则应该使用公平锁,因为非公平锁带来的吞吐量提升可能不会出现。 减少锁竞争 1. 减少锁的持有时间:使用同步代码块 2. 降低锁的请求频率:锁分解和锁分段 3. 放弃独占锁:使用并发容器,读写锁,不可变对象,原子变量。 锁分解: 如果一个锁需要保护多个相互独立的状态变量,那么可以将这个锁分解为多个锁,每个锁只保护一个变量 锁分段: 劣势:获取多个锁实现独占访问时,获取更加困难并且开销更大。比如 jdk1.7 之前 ConcurrentHashMap 的 size()

Can a thread call wait() on two locks at once in Java (6)

南楼画角 提交于 2019-12-02 11:28:32
I've just been messing around with threads in Java to get my head around them (it seems like the best way to do so) and now understand what's going on with synchronize, wait() and notify(). I'm curious about whether there's a way to wait() on two resources at once. I think the following won't quite do what I'm thinking of ( edit : note that the usual while loops have been left out of this example to focus just on freeing up two resources ): synchronized(token1) { synchronized(token2) { token1.wait(); token2.wait(); //won't run until token1 is returned System.out.println("I got both tokens back

HttpClient的连接管理器相关

情到浓时终转凉″ 提交于 2019-12-02 11:26:38
注意 public class ClientEvictExpiredConnections { public static void main(String[] args) throws Exception { PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); // 设置最大连接数 cm.setMaxTotal(200); // 设置每个主机地址的并发数 cm.setDefaultMaxPerRoute(20); new IdleConnectionEvictor(cm).start(); } public static class IdleConnectionEvictor extends Thread { private final HttpClientConnectionManager connMgr; private volatile boolean shutdown; public IdleConnectionEvictor(HttpClientConnectionManager connMgr) { this.connMgr = connMgr; } @Override public void run() { try { while (!shutdown)

synchronized关键字的内存语义

风流意气都作罢 提交于 2019-12-02 11:25:42
以下内容摘自:Java并发编程之美 加锁和释放锁的语义:当获取锁以后会清空锁块内本地内存中将会被用到的共享变量,在使用这些共享变量的时从主内存进行加载,在释放锁时将本地内存中修改的 共享变量刷新到主内存中。 进入synchronized块的内存语义是把在synchronized块内使用到的变量从线程的工作内存中清除,这样在synchronized块中使用到该变量时就不会从线程的工作内存中 获取,而是直接从主内存中获取。推出synchronized块的内存语义是把在synchronized块内对共享变量的修改刷新到主内存。。 摘了两段,还是直接看书吧。 来源: https://www.cnblogs.com/cold-windy/p/11743013.html