java 多线程关键字

线程安全解释:

我们之前给出了同步基本思想的三个点,我们也说了jvm的三种锁都是以基本思想为基础的,而这三种锁在第1、2点的实现上本质上是一样的:

  1. 在共享数据里保存一个锁 //java同步是通过synchronized关键字实现的,synchronized有三种用法:一种是同步块,这种用法需要指明一个锁定对象;一种是修饰静态方法,这种用法相当于锁定Class对象;一种是修饰普通方法,这种用法相当于锁定方法所在的实例对象。因此,在java里能够被synchronized关键字锁定的一定是对象,因此就要在对象里保存一个锁,而对象内存结构里的MarkWord就可以认为是这个锁。三种锁虽然实现细节不同,但是都是使用MarkWord保存锁的。
  2. 在锁里保存这个线程的标识 //偏向锁是在MarkWord里保存线程id,轻量级锁是在MarkWord里保存指向拥有锁的线程栈中锁记录的指针,重量级锁是在MarkWord中保存指向互斥量的指针(互斥量只向一个线程授予对共享资源的独占访问权,可以认为是记录了线程的标识)而区分这三种锁的关键,就是同步基本思想的第三点:
  3. 其他线程访问已加锁共享数据要等待锁释放 //这里的等待锁释放是一个抽象的说法,并没有严格要求怎么等待。而重量级锁因为使用了互斥量,这里的等待就是线程阻塞。使用互斥量可以保证所有情况下的并发安全,但是使用互斥量会带来较大的性能消耗。而且在实际的项目代码中,很可能一段本来不会有并发情况的代码被加了锁,这样每次使用互斥量就白白消耗了性能。能不能先假设被加锁的代码不会有并发的情况,等到发现有并发的时候再使用互斥量呢?答案是可以的,轻量级锁和偏向锁都是基于这种假设来实现的。
    1. 其实抛开实现的细节,java的多线程很简单:

    java多线程主要面临的问题就是线程安全问题.
    线程安全问题是由线程间的通信造成的,

多个线程间不通信就没有线程安全问题  
java中线程通信只能通过类变量和实例变量,因此解决线程安全问题就是解决对变量的安全访问问题  
java中解决变量的安全访问采用的是同步的手段,同步是通过锁实现的
有三种锁能保证变量只有一个线程访问,偏向锁最快但是只能用于从始至终只有一个线程获得锁,轻量级锁较快但是只能用于线程串行获得锁,重量级锁最慢但是可以用于线程并发获得锁,先用最快的偏向锁,每次假设不成立就升级一个重量。

Java 类文件编译时,所有变量和方法的引用都被当做符号引用存储在这个类的常量池中。符号引用是一个逻辑引用,实际上并不指向物理内存地址。JVM 可以选择符号引用解析的时机,一种是当类文件加载并校验通过后,这种解析方式被称为饥饿方式。另外一种是符号引用在第一次使用的时候被解析,这种解析方式称为惰性方式。无论如何 ,JVM 必须要在第一次使用符号引用时完成解析并抛出可能发生的解析错误。绑定是将对象域、方法、类的符号引用替换为直接引用的过程。绑定只会发生一次。一旦绑定,符号引用会被完全替换。如果一个类的符号引用还没有被解析,那么就会载入这个类。每个直接引用都被存储为相对于存储结构(与运行时变量或方法的位置相关联的)偏移量

 

Synchronize:

synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
1. 修饰一个代码块,被修饰的代码块称同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

 

vo

posted @ 2020-03-07 22:04  漫漫人生路322  阅读(345)  评论(0编辑  收藏  举报