synchronized

java多线程:synchronized和lock比较浅析

醉酒当歌 提交于 2020-01-26 17:38:51
转载:http://www.toutiao.com/a6392135944652587266/?tt_from=weixin&utm_campaign=client_share&app=news_article&utm_source=weixin&iid=7704173001&utm_medium=toutiao_ios&wxshare_count=1 synchronized是基于jvm底层实现的数据同步,lock是基于Java编写,主要通过硬件依赖CPU指令实现数据同步。下面一一介绍 一、synchronized 的实现方案 1. synchronized能够把任何一个非null对象当成锁,实现由两种方式: a.当synchronized作用于非静态方法时,锁住的是当前对象的事例,当synchronized作用于静态方法时,锁住的是class实例,又因为Class的相关数据存储在永久带,因此静态方法锁相当于类的一个全局锁。 b.当synchronized作用于一个对象实例时,锁住的是对应的代码块。 2.synchronized锁又称为对象监视器(object)。 3.当多个线程一起访问某个对象监视器的时候,对象监视器会将这些请求存储在不同的容器中。 >Contention List:竞争队列,所有请求锁的线程首先被放在这个竞争队列中 >Entry List:Contention

如何实现线程安全?

谁说我不能喝 提交于 2020-01-26 15:08:00
文章目录 避免共享 不可变 可重入代码 线程封闭 必须共享 互斥同步 非阻塞同步 什么是线程安全?下面是我摘自java并发编程书里给的解释: 当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。 这个解释听的是不是云里雾里?我们说的通俗一点: 线程安全就是多线程并发访问的时候,线程之间所共享的资源不会被污染或被破坏。 我们知道线程共享的内存区域主要就是java堆,而java堆主要存的就是对象和数组,所有的全局变量都存储在堆中。也就是说我们想保证线程安全,就需要保证全局变量和堆内的对象不会受其他线程影响。 由此,我们可以从数据共享和不共享两个方面来讨论实现线程安全的方式。 避免共享 通过避免共享,让所有资源都编程线程私有,达到线程安全。主要实现方法有三种: 不可变 可重入代码 线程封闭 不可变 使用final类型 通过使用final类型修饰,发布不可变对象。 String属于不可变对象,可直接使用。 使用volatile类型 通过使用Volatile类型修饰,发布不可变对象。 volatile类型修饰的变量只适用于读多写少的情况,只能确保其可见性。如果要保证线程安全,则需要保证只有单个线程去修改。 可重入代码 若一个程序或子程序可以安全的被并行执行,则称其为可重入(reentrant),即允许多个进程同时访问。 可重入代码

多线程高并发这一篇就够了不用再去别家了

微笑、不失礼 提交于 2020-01-26 14:34:10
  高伸缩性的并发编程是一种艺术,是成为高级程序员的必备知识点之一,最近总结了一下相关方面的知识。    借鉴过得博客有的我也不知道原文作业是谁 https://blog.csdn.net/qq_34337272/article/details/81072874 https://www.cnblogs.com/dolphin0520/p/3932921.html 一、线程 什么是线程? 线程是进程中单一顺序的控制流。 什么是进程? 进程是程序运行的过程。 1、进程与线程的关系: 1)线程是进程的最小执行单元; 2)一个进程中至少存在一个线程; 3)线程决定进程的生命周期 —— 一个线程启动,进程就开始执行;所有线程执行结束,这个进程执行结束; 4)多个线程共享一个进程的内存空间、一组系统资源。 2、进程与线程的区别: 1)每个进程都有自己的独立的内存空间、一组系统资源,而线程共享所属进程的内存空间、一组系统资源; 进程是独立的,同一个进程的线程是有联系的。 2)进程之间通信开销较大,线程之间通信开销较小。 3、多线程 一个进程中可以同时存在多个线程; 同一个进程中的多个线程之间可以并发执行; 多线程的执行方式:抢占式; 抢占CPU资源,计算机由CPU执行程序,只有拥有CPU资源的程序,才会被执行。 CUP资源:CUP的控制权,这个控制权具有时间性,时间长度是随机的;这段时间非常短

线程基础,多线程架构,高并发,线程安全基础知识

北慕城南 提交于 2020-01-26 13:55:59
线程基础 一、线程安全 1.1 概念 :当多个线程访问某一个类(对象或者方法)时,这个类始终都能表现出正确额行为,那么这个类(对象或者方法)就是线程安全的。 1.2 synchronized :可以在任何对象或者方法上加锁,二加锁的这段代码称为“互斥区”或者临界区。 例子: package com.nbkj.thread; /** * @author hsj * */ public class MyThread extends Thread { private static int count = 20; @Override public synchronized void run() { count--; System.out.println("count的值是:" + count); System.out.println("当前的线程是:"+Thread.currentThread().getName()); } public static void main(String[] args) { /*MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); MyThread t3 = new MyThread(); MyThread t4 = new MyThread(); MyThread t5 = new

JAVA高并发处理------多线程

让人想犯罪 __ 提交于 2020-01-26 13:49:56
线程安全概念: 当多个线程访问某一个类(对象或方法)时,这个对象始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全的。 分析:当多个线程访问myThread的run方法时,以排队的方式进行处理(这里排对是按照CPU分配的先后顺序而定的),一个线程想要执行synchronized修饰的方法里的代码:1 尝试获得锁  2 如果拿到锁,执行synchronized代码体内容;拿不到锁,这个线程就会不断的尝试获得这把锁,直到拿到为止,而且是多个线程同时去竞争这把锁。(也就是会有锁竞争的问题) synchronized: 可以在任意对象及方法上加锁,而加锁的这段代码称为"互斥区"或"临界区"。取得的锁都是对象锁,而不是把一段代码(方法)当做锁,所以代码中哪个线程先执行synchronized关键字的方法,哪个线程就持有该方法所属对象的锁(Lock),在静态方法上加synchronized关键字,表示锁定.class类,类一级别的锁(独占.class类)。 锁对象的改变问题: 例如下面代码中,当lock发生变化后,t1开始后,t2直接开始。如果去掉将lock改变的代码,则是t1结束后t2才会开始。但是同一对象属性的修改不会影响锁的情况,比如下面代码的lock现在是一个带属性的对象,如果改变该对象的属性,结果还是t1结束后t2才会开始。 package com.bjsxt.base

面试-关键字

╄→гoц情女王★ 提交于 2020-01-26 09:52:12
一、请你讲讲Java里面的final关键字是怎么用的? 答:①final修饰一个类时,表示这个类不能被继承。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为fianl方法。 ②使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义。第二个原因就是效率。在早期的Java实现版本中,会将fianl方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。 ②final修饰一个变量。如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。 二、请你谈谈关于Synchronized和lock? 答:synchronized是Java关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 Lack是一个接口,而synchronized是java关键字,synchronized是内置的语言实现;synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象的发生;而Lock在发生异常时,如果没有主动通、过unlock()去释放锁,则很可能造成死锁现象

Java多线程基础中

别等时光非礼了梦想. 提交于 2020-01-26 05:35:06
多线程 并发 定义:同一个对象多个线程同时操作 线程同步 锁机制(synchronized) 1.synchronized方法 在方法名前加synchronized public synchronized void test ( ) { } 2.synchronized块 synchronized ( obj ) { } 死锁 产生:过多的同步造成相互不释放资源,从而相互等待,一般发生于同步中持有多个对象。 解决:不要在一个代码块中持有多个对象的锁就可以了。 并发协作(生产者消费者模式) 1.管程法: 案例:借助容器实现进程间的通信 public class test09 { public static void main ( String [ ] args ) { SynContainer container = new SynContainer ( ) ; new Producter ( container ) . start ( ) ; new Customer ( container ) . start ( ) ; } } //生产者 class Producter extends Thread { SynContainer container ; public Producter ( SynContainer container ) { this . container

synchronized

五迷三道 提交于 2020-01-25 23:31:26
什么是synchronized? synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法(或者该类的其他同步方法),有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,锁定调用者,然后直接运行。它包括两种用法:synchronized 方法和 synchronized 块。 Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍可以访问该object中的非加锁代码块。 为什么使用synchronized? synchronized的用法: 同步代码块和同步方法, //同步方法 public synchronized void test3() { try { System.out.println("this is the public_lock SyncTest.class and thread name is " +

synchronized实现原理

送分小仙女□ 提交于 2020-01-25 09:09:43
Java中每一个对象都可以作为锁,这是synchronized实现同步的基础: 普通同步方法,锁是当前实例对象 静态同步方法,锁是当前类的class对象 同步方法块,锁是括号里面的对象 当一个线程访问同步代码块时,它首先是需要得到锁才能执行同步代码,当退出或者抛出异常时必须要释放锁, Jconsole :java安装目录下有个jdk中找到jconsole 反编译: 通过javap反编译class文件: 反编译后,我们可以看到Java编译器为我们生成的字节码。在对于 doSth 和 doSth1 的处理上稍有不同。也就是说。JVM对于同步方法和同步代码块的处理方式不同。 对于同步方法,JVM采用 ACC_SYNCHRONIZED 标记符来实现同步。 对于同步代码块。JVM采用 monitorenter 、 monitorexit 两个指令来实现同步。 Monitorenter Monitorexit 从上面可以看出,同步代码块是使用monitorenter和monitorexit指令实现的,同步方法(在这看不出来需要看JVM底层实现)依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。 同步代码块 :monitorenter指令插入到同步代码块的开始位置,monitorexit指令插入到同步代码块的结束位置

java 线程安全 Lock

那年仲夏 提交于 2020-01-25 07:20:49
 java.util.concurrent.locks   对于线程安全我们前面使用了synchronized关键字,对于线程的协作我们使用Object.wait()和Object.notify()。在JDK1.5中java为我们提供了Lock来实现与它们相同的功能,并且性能优于它们,在JDK1.6时,JDK对synchronized做了优化,在性能上两种方式差距不大了。 一、为什么出现lock   synchronized修饰的代码块,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,如果没有释放则需要无限的等待下去。获取锁的线程释放锁只会有两种情况:   1、获取锁的线程执行完了该代码块,然后线程释放对锁的占有。   2、线程执行发生异常,此时JVM会让线程自动释放锁。 Lock与synchronized对比:   1、Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问。   2、synchronized不需要手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。 二、java.util