synchronized

JSR133给Java内存模型定义的happen-before规则

依然范特西╮ 提交于 2020-03-11 17:43:38
单线程规则:同一个线程中的每个操作都happens-before于出现在其后的任何一个操作。 对一个监视器的解锁操作happens-before于每一个后续对同一个监视器的加锁操作。 对volatile字段的写入操作happens-before于每一个后续的对同一个volatile字段的读操作。 Thread.start()的调用操作会happens-before于启动线程里面的操作。 一个线程中的所有操作都happens-before于其他线程成功返回在该线程上的join()调用后的所有操作。 一个对象构造函数的结束操作happens-before与该对象的finalizer的开始操作。 传递性规则:如果A操作happens-before于B操作,而B操作happens-before与C操作,那么A动作happens-before于C操作。 实际上这组happens-before规则定义了操作之间的内存可见性,如果A操作happens-before B操作,那么A操作的执行结果(比如对变量的写入)必定在执行B操作时可见。 为了更加深入的了解这些happens-before规则,我们来看一个例子: //线程A,B共同访问的代码 Object lock = new Object(); int a=0; int b=0; int c=0; //线程A,调用如下代码

好程序员:大数据之线程高级部分

妖精的绣舞 提交于 2020-03-11 16:36:10
好程序员:大数据之线程高级部分,首先讲一下线程的生命周期 对于一个线程, 在被创建后, 不是立即就进入到了运行状态, 也不是一直处于运行状态, 在线程的声明周期中, 一个线程会在多种状态之间进行切换 new : 新生状态, 线程被实例化, 但是还没有开始执行(start) runnable: 就绪状态, 已经执行过start, 线程已经启动了, 只是没有抢到CPU时间片 running: 运行状态, 抢到了CPU时间片 blocked: 阻塞状态, 线程执行的过程中, 遇到一些特殊情况, 会进入阻塞状态. 阻塞中的线程, 是不能参数时间片的抢夺的 (不能被线程调度器调度) dead: 死亡状态, 线程终止 ​ 正常死亡 : run方法中的代码执行结束 ​ 非正常死亡 : 强制使用stop方法停止这个线程 临界资源问题 由于线程之间是资源共享的。如果有多个线程,同时对一个数据进行操作,此时这个数据会出现问题。 如果有一个线程在访问一个临界资源,在访问之前,先对这个资源“上锁”,此时如果有其他的线程也需要访问这个临界资源,需要先查这个资源有没有被上锁,如果没有被上锁,此时这个线程可以访问这个资源;如果上锁了,则此时这个线程进入阻塞状态,等待解锁。 ####同步代码段 // 同步代码段 // 小括号:就是锁 // 大括号:同步代码段,一般情况下,写需要对临界资源进行的操作

彻底理解synchronized关键字

老子叫甜甜 提交于 2020-03-11 12:57:35
先看现象,再做总结。 业务场景,模拟很多人在抢票。 public class SynchronizredDemo { static int tickets = 1000; public void saleTickets() { int i = 1; while (i > 0) { i--; tickets--; System.out.println(Thread.currentThread().getName() + "----" + tickets); } } public static void main(String[] args) { final SynchronizredDemo demoA = new SynchronizredDemo(); final long awaitTime = 2 * 10000; ExecutorService executorService = new ThreadPoolExecutor(1000, 1000, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10)); for (int j = 0; j < 1000; j++) { executorService.execute(new Runnable() { @Override public void run() {

多线程创建方式及线程安全问题

女生的网名这么多〃 提交于 2020-03-11 07:42:46
1.创建线程方式 一: 创建线程方式一继承 Thread 类 public clsss MyThread extends Thread{ //重写 run方法 ,设置线程任务 Run(){ } } main(){ new MyThread().start(); } 获取线程名称: Thread.currentThread()获取当前线程对象 Thread.currentThread().getName();获取当前线程对象的名称 二: 创建线程方式 — 实现 Runnable 接口 创建线程的步骤。 1、定义类实现 Runnable接口。 2、覆盖接口中的 run方法。。 3、创建 Thread类的对象 4、将 Runnable接口的子类对象作为参数传递给 Thread类的构造函数。 5、调用 Thread类的 start方法开启线程。 l 代码演示: public class Demo02 { public static void main(String[] args) { // 创建线程执行目标类对象 Runnable runn = new MyRunnable(); // 将 Runnable 接口的子类对象作为参数传递给 Thread 类的构造函数 Thread thread = new Thread(runn); Thread thread2 = new Thread

Dubbo基本原理机制

|▌冷眼眸甩不掉的悲伤 提交于 2020-03-11 06:49:10
转自:http://blog.csdn.net/paul_wei2008/article/details/19355681 分布式服务框架: –高性能和透明化的RPC远程服务调用方案 –SOA服务治理方案 -Apache MINA 框架基于Reactor模型通信框架,基于TCP长连接 Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。 分析源代码,基本原理如下: client一个线程调用远程接口,生成一个唯一的ID(比如一段随机字符串,UUID等),Dubbo是使用AtomicLong从0开始累计数字的 将打包的方法调用信息(如调用的接口名称,方法名称,参数值列表等),和处理结果的回调对象callback,全部封装在一起,组成一个对象object 向专门存放调用信息的全局ConcurrentHashMap里面put(ID, object) 将ID和打包的方法调用信息封装成一对象connRequest,使用IoSession.write(connRequest)异步发送出去 当前线程再使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 再先检测是否已经获取到结果,如果没有,然后调用callback的wait(

Dubbo基本原理机制

被刻印的时光 ゝ 提交于 2020-03-11 05:26:57
分布式服务框架: –高性能和透明化的RPC远程服务调用方案 –SOA服务治理方案 -Apache MINA 框架基于Reactor模型通信框架,基于tcp长连接 Dubbo缺省协议采用单一长连接和NIO异步通讯, 适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况 分析源代码,基本原理如下: client一个线程调用远程接口,生成一个唯一的ID(比如一段随机字符串,UUID等),Dubbo是使用AtomicLong从0开始累计数字的 将打包的方法调用信息(如调用的接口名称,方法名称,参数值列表等),和处理结果的回调对象callback,全部封装在一起,组成一个对象object 向专门存放调用信息的全局ConcurrentHashMap里面put(ID, object) 将ID和打包的方法调用信息封装成一对象connRequest,使用IoSession.write(connRequest)异步发送出去 当前线程再使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 再先检测是否已经获取到结果,如果没有,然后调用callback的wait()方法,释放callback上的锁,让当前线程处于等待状态。 服务端接收到请求并处理后,将结果(此结果中包含了前面的ID,即回传

你必须要知道的锁原理、锁优化、CAS、AQS

孤者浪人 提交于 2020-03-10 16:23:18
1、为什么要用锁? 锁-是为了解决并发操作引起的脏读、数据不一致的问题。 2、锁实现的基本原理 2.1、volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁要更加方便。 volatile在多处理器开发中保证了共享变量的“ 可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。 结论:如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。 2.2、synchronized synchronized通过锁机制实现同步。 先来看下利用synchronized实现同步的基础:Java中的每一个对象都可以作为锁。 具体表现为以下3种形式。 对于普通同步方法,锁是当前实例对象。 对于静态同步方法,锁是当前类的Class对象。 对于同步方法块,锁是Synchonized括号里配置的对象。 当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。 2.2.1 synchronized实现原理 synchronized是基于Monitor来实现同步的。 Monitor从两个方面来支持线程之间的同步: 互斥执行 协作 1、Java

关键字面试题参考

邮差的信 提交于 2020-03-10 08:00:52
● 请你讲讲Java里面的final关键字是怎么用的? 考察点:关键字 参考回答:当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。“使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。“对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。 ● 请你谈谈关于Synchronized和lock 考察点:java关键字 参考回答:synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。JDK1.5以后引入了自旋锁、锁粗化、轻量级锁,偏向锁来有优化关键字的性能。Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现

Thinking in java学习笔记19:第二十一章(并发-中)

∥☆過路亽.° 提交于 2020-03-09 13:43:51
上一个笔记(并发-上)的内容: https://blog.csdn.net/asdfghj253/article/details/104050967 3.共享受限资源 3.1 不正确地访问资源 这节举了个例子来说明,我总结一下。那就是资源的原子性和可视性。 这里将资源设置了状态,并编写方法来提供资源是否可用的可观性,当状态为不可用,那么其他线程无法调用,等一线程结束状态改回可用,再给下一个线程使用。 3.2 解决共享资源竞争 上面那节主要是当一种思维来讲的,根据这个思维,这边讲了线程现在使用的一个资源机制,互斥和共享,通过加锁来解决并发模式的线程问题。这些都是采用序列化访问共享资源的方案:在给定时刻只允许一个任务访问共享资源。 而锁往往是锁一段代码,所以一段时间内只会有一个任务可以运行这段代码 3.2.1 synchronized 关键字 (同步) java提供 synchronized 关键字(同步)来防止资源冲突,这个关键字将会检查锁是否可用,然后获取锁。执行代码,最后释放锁。 例: synchronized void test(){ ......} 这个test函数,一个时间段内只有一个任务可以调用。调用完释放锁,给下一个任务使用。 注意:使用 synchronized 的话,将里面的域(成员)设置成private是非常重要的,否则 synchronized

synchronized如何高中有序性的

不想你离开。 提交于 2020-03-09 12:15:58
问题: 为什么会出现指令重排? 计算机为提升程序执行性能,可以在硬件层面和程序处理器层面做一些优化,指令重排就是优化方式之一。 指令重排会引起什么问题? 由于程序处理器进行了指令重排,可能会引起程序执行有序性的问题。 如何解决程序执行有序性问题? 针对因程序处理器层面指令重排造成的有序性问题,最简单的方法就是禁止处理器优化和做指令重排,可以通过volatile中使用内存屏障来保证。 硬件层面可遵循as-if-serial语义解决有序性问题,当程序层面是单线程执行的,那么硬件层面优化必须遵循as-if-serial语义,从而解决了硬件层面优化造成的程序执行一致性问题。 java中通过synchronized提供的锁机制,确保了在加锁和解锁过程中的逻辑执行是单线程的,也就满足了符合as-if-serial语义,从而实现了有序性。 来源: oschina 链接: https://my.oschina.net/u/1000241/blog/3190416