synchronized

线程总结

假如想象 提交于 2020-02-11 17:07:12
线程总结 线程主要涉及的内容以下几点 一、如何创建(Runnable,Thread,匿名类(lambda))线程 二、多线程下的同步和互斥 三、线程池 四、Lock锁(jdk 1.5) 与synchronized之间的区别 五、原子操作 (以后有学习到新的再进行补充,新手描述嘤嘤嘤) 一.如何创建线程   首先需要分清线程和进程之间的区别,简单的来说在java中执行一个可执行程序,可以称它为进程。在启动main方法时,就启动了一个java.exe进程。在main方法中还可以产生额外的线程(程序执行的最小单位),这样就包括了main线程和其他线程。 1、继承Thread public class MyThread extends Thread { //重写run方法 public void run() { //需要线程执行的代码 ; } } //start()为开始方法,只有执行了,线程才开始启动 new MyThread().start(); 2、实现Runnable public class MyThread implements Runnable { //重写run方法 public void run() { //需要线程执行的代码 ; } } new Thread(new MyThread()).start(); 3、匿名类 new Thread() { public

线程同步与锁

时光怂恿深爱的人放手 提交于 2020-02-11 14:35:41
文章目录 1、线程同步问题(synchronized) 1.1、Web123606 1.2、银行账户取钱 1.3、线程容器 2、可重入锁( *ReentrantLock* ) 2.0、介绍 2.1、使用ReentranLock 2.2、ReentrantLock可响应中断 2.3、获取锁限时等待(更好解决死锁问题) 2.4、结合Condition实现等待通知机制(线程之间的通信) 2.4.1、Condition使用简介 2.4.2、使用Condition实现简单的阻塞队列(生产者消费者) 2.5、测试可重复锁 2.6、实现不可重复锁 2.7、实现可重入锁(ReentranLock的实现) 3、队列与锁 3.0、锁对象 3.1、Synchronized关键字 3.1.1、Synchronized方法 3.1.2、Synchronized同步块 3.1.3、锁的粒度小,提升性能 3.1.4、共享例子 3.2、死锁 3.3、单例模式 4、Volatile关键字(不多见) 5、ThreadLocal 每个线程有自己的空间 6、原子性 7、锁的分类 1、线程同步问题(synchronized) Brian Goetz给出了下述“同步格言”:“如果向一个变量写入值,而这个变量接下来可能会被另一个线程读取,或者,从一个变量读值,而这个变量可能是之前被另一个线程写入的,此时必须使用同步。

线程的状态有哪些,线程中的start与run方法的区别

こ雲淡風輕ζ 提交于 2020-02-11 08:25:00
线程在一定条件下,状态会发生变化。线程一共有以下几种状态: 1、新建状态(New):新创建了一个线程对象。 2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取 CPU 的使用权。即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。 3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。 4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。 阻塞的情况分三种: (1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒, (2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。 (3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。 5、死亡状态(Dead):线程执行完了或者因异常退出了run(

Java线程的状态分析

主宰稳场 提交于 2020-02-11 07:01:54
线程状态 1、新建状态(New):新创建了一个线程对象。 2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取 CPU 的使用权。即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。 3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。 4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。 阻塞的情况分三种: (1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒, (2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。 (3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。 5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。 New :

关键字

半腔热情 提交于 2020-02-11 02:19:24
Synchronized 介绍 synchronized是Java实现同步的一种机制,它属于Java中关键字,是一种jvm级别的锁。synchronized锁的创建和释放是此关键字控制的代码的开始和结束位置,锁是由jvm控制的创建和释放的,正是因为这一点,synchronized锁不需要手动释放,哪怕是代码出现异常,jvm也能自动释放锁。 为什么要使用synchronized 在并发编程中存在线程安全问题,主要原因有:1.存在共享数据 2.多线程共同操作共享数据。关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的变化可见(可见性),即可以代替volatile。 实现原理 synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性 应用方式 对于普通的同步方法: 锁是当前的对象 对于静态函数的同步方法: 锁是静态函数所在类的class对象 对于同步方法块的内容: 锁是指Synchonized括号里配置的对象 volatile Java程序中,为了提高程序运行效率,编译器会自动对其进行优化,把经常被访问的变量缓存起来,程序在读取变量时可能直接从缓存(例如寄存器)中来读取这个值,而不会从内存中取。但当遇到多线程编程时

并发进阶

时间秒杀一切 提交于 2020-02-10 21:54:37
synchronized:1、 说一说自己对于 synchronized 关键字的了解 synchronized关键字解决的是多个线程间访问资源的同步性,它可以保证被它修饰的方法或者代码块在任意时刻都只能有一个线程执行。 2. 说说自己是怎么使用 synchronized 关键字,在项目中用到了吗 synchronized加到static静态方法和synchronzied(class)代码块上都是给Class类加锁。 synchronzied加到实例方法和synchronized(this)代码块上都是给对象实例加锁。 3、单例模式了解吗?来给我手写一下!给我解释一下双重检验锁方式实现单例模式的原理 public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton getUniqueInstance() { //先判断对象是否已经实例过,没有实例化过才进入加锁代码 if (uniqueInstance == null) { //类对象加锁 synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new

2020 Java面试题最新(五锁机制)

无人久伴 提交于 2020-02-10 17:44:28
锁的原因都是由并发问题发生的,在此我只是写一些面试中可能会问到的问题以及问题的答案,并不是给大家深入的讲解锁机制 一般面试官问都是从一个点引入一个点的问问题,所以我就先从线程问题引入到锁问题 1.说说线程安全问题 线程安全是多线程领域的问题,线程安全可以简单理解为一个方法或者一个实例可以在多线程环境中使用而不会出现问题 在 Java 多线程编程当中,提供了多种实现 Java 线程安全的方式: 最简单的方式,使用 Synchronization 关键字 使用 java.util.concurrent.atomic 包中的原子类,例如 AtomicInteger 使用 java.util.concurrent.locks 包中的锁 使用线程安全的集合 ConcurrentHashMap 使用 volatile 关键字,保证变量可见性(直接从内存读,而不是从线程 cache 读) 2.volatile 实现原理 在 JVM 底层 volatile 是采用“内存屏障”来实现的 缓存一致性协议(MESI协议)它确保每个缓存中使用的共享变量的副本是一致的。其核心思想如下:当某个 CPU 在写数据时,如果发现操作的变量是共享变量,则会通知其他 CPU 告知该变量的缓存行是无效的,因此其他 CPU 在读取该变量时,发现其无效会重新从主存中加载数据 3.synchronize 实现原理

Think In Java 21.3.5 临界区

做~自己de王妃 提交于 2020-02-10 17:33:04
有时,你只是希望防止多个线程同时访问方法内部的部分代码而不是防止访问整个方法。通过这种方式分离出来的代码段被称为 临界区(critical section) ,它也使用synchronized关键字建立。这里,synchronized被用来指定某个对象,此对象的锁被用来对花括号内的代码进行同步控制: synchronized(syncObject){ // This code can be accessed by only one task at a time } 这也被称为 同步控制块 ;在进入此段代码前,必须得到syncObject对象的锁。如果其他线程已经得到这个锁,那么就得等到锁被释放以后,才能进入临界区。 通过使用同步控制块,而不是对整个方法进行同步控制,可以使多个任务访问对象的时间性能得到显著提高,下面的例子比较了这两种同步控制方法。此外,它也演示了如何把一个非保护类型的类,在其他类的保护和控制之下,应用于多线程的环境: package lime.tij._021._003._005; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutorService; import java.util

并发编程之第三篇(synchronized)

与世无争的帅哥 提交于 2020-02-10 12:02:55
并发编程之第三篇(synchronized) 3. 自旋优化 4. 偏向锁 撤销-其它线程使用对象 撤销-调用wait/notify 批量重偏向 批量撤销 5. 锁消除 4.7 wait/notify API介绍 4.8 wait notify的正确姿势 同步模式之保护性暂停 异步模式之生产者/消费者 4.9 Park & Unpark 原理之park & unpark 4.10 重新理解线程状态转换 3. 自旋优化 重量级锁竞争的时候,还可以使用自旋来进行优化,如果当前线程自旋成功(即这时候持锁线程已经退出了同步块,释放了锁),这时当前线程就可以避免阻塞。 自旋重试成功的情况 自旋重试失败的情况 在Java6之后自旋锁是自适应的,比如对象刚刚的一次自旋操作成功过,那么认为这次自旋成功的可能性会高,就多自旋几次;反之,就少自旋甚至不自旋,总之,比较智能。 自旋会占用CPU时间,单核CPU自旋就是浪费,多核CPU自旋才能发挥优势。 Java7之后不能控制是否开启自旋功能 4. 偏向锁 轻量级锁在没有竞争时(就自己这个线程),每次重入任然需要执行CAS操作。 Java6中引入了偏向锁来做进一步优化 :只有第一次使用CAS将线程ID设置到对象的Mark Word头,之后发现这个线程ID是自己的就表示没有竞争,不用重新CAS。以后只要不发生竞争,这个对象就归该线程所有 例如 : 偏向状态

[一]多线程编程-实现及锁机制

跟風遠走 提交于 2020-02-10 04:14:24
顺着我的思路,一步一步往下看,你会有所收获。。。。 实现多线程有两种方式,代码如下 1.继承Thread类: code1: public class Test { public static void main(String[] args) { Ticket ticket = new Ticket(); ticket.start(); } } class Ticket extends Thread{ @Override public void run() { System.out.println("Hello ...."); } } 执行结果:Hello .... 2.实现Runnable接口 code2: public class Test { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(ticket).start(); } } class Ticket implements Runnable{ @Override public void run() { System.out.println("Hello ...."); } } 执行结果:Hello .... 在Java API 中,我们可以找到很多Thread封装的方法,当我们创建的线程数比较多的时候