synchronized

多线程(4)线程生命周期

寵の児 提交于 2020-04-02 14:00:12
多线程有六个状态 1.New(新创建) : 已创建但是还没有启动的新线程, new Thread()还没执行start() 2.Runnable( 可运行) :, 包括start()后等待运行和拿到资源运行中 3.Blocked(被阻塞) : synchronized修饰的代码没有拿到锁(monitor)陷入的等待状态。注意必须是synchronized修饰,其他的锁不是 4.Waiting(等待) : Object.wait(), Thread.join(), LockSupport.park()这三个没有timeout参数的方法会让线程进入等待状态. Object.notify()或者Object.notifyAll(), 等待join方法所运行的线程执行完毕, LockSupport.unpark() 会让等待的线程进入可运行状态 Lock.lock进入的是waiting状态而不是Blocked waiting和blocked的区别根本原因是“是不是内置锁”。Lock不是Java语言支持的锁,是JDK包提供的,而synchronized是关键字级别是,它们不一样。 5.Timed Waiting(计时等待) : 等待的那三个方法带了时间参数, 超时会自动唤醒也可以被notify等唤醒 6.Terminated(被终止) :run方法正常执行完,run被未捕获的异常终止 注意:

普通锁和分布式锁

谁说我不能喝 提交于 2020-04-02 09:33:57
1、普通锁和分布式锁 为什么有了普通锁还需要分布式锁,当然是因为普通锁和分布式锁各有各的使用场景。普通针对多线程的场景,一般可以synchronized和lock。而分布式针对的是分布式的环境,系统部署在多个机器中,也会出现并发问题,并且场景是多个进程之间的并发问题。使用内存标记无法解决这个问题,因为内存是线程共享的。 2、普通锁 主要有两种synchronized和lock。下面介绍一下两个锁的异同点: 1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;   2)synchronized除了在流程走完释放锁,还在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock 时需要在finally块中释放锁;   3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;当通过lockInterruptibly()方法获取某个锁时,如果不能获取到,只有进行等待的情况下,是可以响应中断的。   4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。   5)Lock可以提高多个线程进行读操作的效率

Java并发(思维导图)

北城以北 提交于 2020-04-01 01:47:18
1,线程状态转换 无限期等待: 限期等待: 线程生命流程: 2,实现方式 代码实现样例【三种方式】: package com.cnblogs.mufasa.demo2; import java.util.concurrent.Callable; public class test1_Runnable implements Runnable{ @Override public void run() { for(int i=0;i<50;i++){ System.out.println("当前线程:"+i); } } } class test2_Callable implements Callable<String> { private int num; public test2_Callable(){} public test2_Callable(int num){ this.num=num; } @Override public String call() throws Exception { for(int i=0;i<50;i++){ System.out.println(this.num+"线程:"+i); } return num+"线程已完成"; } } class test3_Thread extends Thread { private int num; public

JAVA多线程之wait/notify

…衆ロ難τιáo~ 提交于 2020-03-30 14:34:55
本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法。 ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait() 与 notify/notifyAll() 的执行过程 ③中断 调用wait()方法进入等待队列的 线程 ④notify 通知的顺序不能错 ⑤多线程中测试某个条件的变化用 if 还是用 while? ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 wait() 与 notify/notifyAll() 是Object类的方法,在执行两个方法时,要先获得锁。那么怎么获得锁呢? 在这篇: JAVA多线程之Synchronized关键字--对象锁的特点 文章中介绍了使用synchronized关键字获得锁。因此,wait() 与 notify/notifyAll() 经常与synchronized搭配使用,即在synchronized修饰的同步代码块或方法里面调用wait() 与 notify/notifyAll()方法。 ②wait() 与 notify/notifyAll() 的执行过程 由于 wait() 与 notify/notifyAll() 是放在同步代码块中的, 因此线程在执行它们时,肯定是进入了临界区中的,即该线程肯定是获得了锁的。

java中volatile,synchronized关键字

人盡茶涼 提交于 2020-03-30 12:59:54
volatile是变量修饰符,而synchronized则是作用于一段代码或方法;如下三句get代码: 1 int i1; 2 int geti1() {return i1;} 3 4 volatile int i2; 5 int geti2() {return i2;} 6 7 int i3; 8 synchronized int geti3() {return i3;} geti1() 得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。 在Java内存模型中,有main memory(主内存区域),这里存放了变量目前的“准确值”,每个线程也有自己的memory(例如寄存器)。为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。 geti2() 得到的是main

Java中关键字volatile 和 synchronized 的作用和区别

邮差的信 提交于 2020-03-30 12:59:41
volatile是变量修饰符,而synchronized则是作用于一段代码或方法 ;如下三个get方法的代码: 1 int i1; 2 int geti1() {return i1;} 3 4 volatile int i2; 5 int geti2() {return i2;} 6 7 int i3; 8 synchronized int geti3() {return i3;} geti1() 得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。 在Java内存模型中,有main memory(主内存区域),这里存放了变量目前的“准确值”,每个线程也有自己的memory(例如寄存器)。为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。 geti2() 得到的是main

并发2-Synchronized

爷,独闯天下 提交于 2020-03-30 12:52:55
一、Synchronized的概念 是利用锁的机制来实现同步的。 锁机制有如下两种特性: 互斥性: 即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。 可见性: 必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。 二、Synchronized的使用 修饰静态方法    //修饰静态方法 public static synchronized void print() { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"runing"); }    修饰非静态方法    //修饰非静态方法 public synchronized void print1() { try { TimeUnit.SECONDS.sleep(1

java内存模型与多线程

我们两清 提交于 2020-03-30 12:48:42
现代计算机,cpu在计算的时候,并不总是从内存读取数据,它的数据读取顺序优先级是:寄存器-高速缓存-内存,线程计算的时候,原始的数据来自内存,在 计算过程中,有些数据可能被频繁读取,这些数据被存储在寄存器和高速缓存中,当线程计算完后,这些缓存的数据在适当的时候应该写回内存,当多个线程同时读 写某个内存数据时,由于涉及数据的可见性、操作的有序性,所以就会产生多线程并发问题。 Java作为平台无关性语言,JLS(Java语言规范)定义了一个统一的内存管理模型 JMM (Java Memory Model),JMM屏蔽了底层平台内存管理细节,在多线程环境中必须解决可见性和有序性的问题。JMM规定了jvm有 主内存 (Main Memory)和 工作内存 (Working Memory) ,主内存存放程序中所有的类实例、静态数据等变量,是多个线程共享的,而工作内存存放的是该线程从主内存中拷贝过来的变量以及访问方法所取得的局部变量, 是每个线程私有的其他线程不能访问,每个线程对变量的操作都是以先从主内存将其拷贝到工作内存再对其进行操作的方式进行,多个线程之间不能直接互相传递数 据通信,只能通过共享变量来进行。 JLS定义了线程对主存的操作指令: read,load,use,assign,store,write 。这些行为是不可分解的原子操作,在使用上相互依赖,read

并发编程面试题

蹲街弑〆低调 提交于 2020-03-29 18:32:53
1.进程和线程还有协程之间的关系   进程:     进程简单理解就是我们平常使用的程序,如QQ,浏览器,网盘等。进程拥有自己独立的内存空间地址,     拥有一个以上的线程。   线程:     线程可以理解为轻量级的进程,是程序执行的最小单元。在某个进程启动后,会默认产生一个主线程,     主线程可以创建多个子线程,   协成:     协成,又称微线程,纤程。协成是一个线程执行,但执行有点像多线程,协成的执行效率极高     简单点说协成是进程和 线程的升级版,进程喝 线程都面临着内内核态和用户态的切换问题而     耗费许多切换时间 ,而且协成就是用户自己控制切换的时机,不再需要 陷入系统的内核态。   一个程序至少有一个进程 ,一个进项至少有一个线程。线程不能独立执行,必须依存在进程中。   协成,应用程序级别(而非操作系统)控制切换,以此来提升 效率。 2.并发和并行之间的区别   并行(parallel):         指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是宏观 来看         二者都是一起执行的。            小结:     当系统有一个以上 CPU 时,则线程的操作有可能非并发。当一个 CPU 执行一个线程时,另一个      CPU 可以执行另一个线程,两个线程互不抢占 CPU 资源,可以同时进行

多线程同步中的门道(二)

纵然是瞬间 提交于 2020-03-29 13:01:14
多线程同步中的门道(二) 前言   在涉及到多线程的开发时,线程同步的考虑是不可缺少的,否则很可能会造成各种超出预料的错误结果。以自己的学习经历来说,对于刚开始接触线程同步的人可能会感觉非常简单,在多线程操作可能会造成数据混乱的地方同步一下不就行了嘛,加个synchronized关键字,多简单!可是随着开发的深入,会渐渐的发现仅仅是一个synchronized关键字也不是那么简单,里面的门道和考虑到的情况还是不少。本系列就着循序渐进的程序和大家探讨一下synchronized关键字使用中的各种情形和会造成的各种意料之外和意料之中的结果,欢迎各位大神轻拍。 转载请注明本文地址: http://www.cnblogs.com/hellojava/p/3635336.html 系列文章: 多线程同步中的门道(一)   synchronized涉及到同步方法、同步代码块、同步类、同步对象、静态方法等,本系列来挨个探讨。   注:因为考虑到文章篇幅和为了突出我们要分析的关键代码,所以下面程序有可能不会是最优写法。 同步代码块   同步代码块,分为同步对象和同步类两种,下面我们来挨个介绍。 同步对象   我们首先来看看一个同步对象的例子。   [测试程序4.1] /** * Test case 4.1. synchronized code block.synchronized object.