写点什么

我看 JAVA 之 线程同步(上)

用户头像
awen
关注
发布于: 1 小时前
我看JAVA 之 线程同步(上)

我看 JAVA 之 线程同步(上)


Java 编程语言的优点之一是它在语言级别支持多线程。这种支持主要集中在同步上:协调多个线程之间的活动和数据访问。Java 用来支持同步的机制是管程 Monitor。本文描述了如何在指令集中支持监视器的,即数据的锁定和解锁。

管程 Monitors

Java 的监视器支持两种线程同步:互斥和协作。互斥(mutualexclusion)是 Java 虚拟机通过对象锁支持的,它使多个线程能够独立地处理共享数据,而不会相互干扰。Java 虚拟机通过类对象的 wait 和 notify 方法支持协作,使线程能够朝着一个共同的目标协同工作。

synchronized 关键字及 wait()/wait(long timeout)/wait(long timeout, int nanos)、notify()/notifyAll() 是 java 管程的组成部分。

对象锁

锁分为对象锁和类锁(Class 对象锁)

同步

同步分为以下两种:

  1. 同步代码块

  2. 同步方法

  3. 同步实例方法

  4. 同步类方法

例子

package chapter07;
public class SyncDemo { private static int counter = 0; publid synchronized void increase() {//synchronize method, object lock counter++; } public void decrease() { synchronized(this) {//synchronize statement, object lock counter--; } } public static synchronized void add() {//static synchronize method, class lock counter++; } public static void main(String [] args) { add(); } }
复制代码

javap 执行后如下片段:

{  public chapter07.SyncDemo();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=1, locals=1, args_size=1         0: aload_0         1: invokespecial #1                  // Method java/lang/Object."<init>":()V         4: return      LineNumberTable:        line 3: 0      LocalVariableTable:        Start  Length  Slot  Name   Signature            0       5     0  this   Lchapter07/SyncDemo;
public synchronized void increase(); descriptor: ()V flags: ACC_PUBLIC, ACC_SYNCHRONIZED Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field counter:I 3: iconst_1 4: iadd 5: putstatic #2 // Field counter:I 8: return LineNumberTable: line 8: 0 line 9: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 this Lchapter07/SyncDemo;
public void decrease(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=3, args_size=1 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: getstatic #2 // Field counter:I 7: iconst_1 8: isub 9: putstatic #2 // Field counter:I 12: aload_1 13: monitorexit 14: goto 22 17: astore_2 18: aload_1 19: monitorexit 20: aload_2 21: athrow 22: return Exception table: from to target type 4 14 17 any 17 20 17 any LineNumberTable: line 12: 0 line 13: 4 line 14: 12 line 15: 22 LocalVariableTable: Start Length Slot Name Signature 0 23 0 this Lchapter07/SyncDemo; StackMapTable: number_of_entries = 2 frame_type = 255 /* full_frame */ offset_delta = 17 locals = [ class chapter07/SyncDemo, class java/lang/Object ] stack = [ class java/lang/Throwable ] frame_type = 250 /* chop */ offset_delta = 4
public static synchronized void add(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED Code: stack=2, locals=0, args_size=0 0: getstatic #2 // Field counter:I 3: iconst_1 4: iadd 5: putstatic #2 // Field counter:I 8: return LineNumberTable: line 18: 0 line 19: 8
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=0, locals=1, args_size=1 0: invokestatic #3 // Method add:()V 3: return LineNumberTable: line 22: 0 line 23: 3 LocalVariableTable: Start Length Slot Name Signature 0 4 0 args [Ljava/lang/String;
static {}; descriptor: ()V flags: ACC_STATIC Code: stack=1, locals=0, args_size=0 0: iconst_0 1: putstatic #2 // Field counter:I 4: return LineNumberTable: line 5: 0}
复制代码


以上例子说明如下:

同步代码块使用 monitorenter 和 monitorexit 两条指令解决同步问题,而同步方法使用 ACC_SYNCHRONIZED 标示。


我看 java 之 线程同步(下)将对对象头、objectmonitor 和 1.6 同步锁优化进行详细介绍。

用户头像

awen

关注

Things happen for a reason. 2019.11.15 加入

还未添加个人简介

评论

发布
暂无评论
我看JAVA 之 线程同步(上)