Java中的Synchronized详解
1.Synchronized简介
Synchronized简称同步锁。 在Java语言中,使用synchronized关键字来标记一个方法或者代码块,当某个线程调用该对象的synchronized方法或者访问synchronized代码块时,这个线程便获得了该对象的锁,其他线程暂时无法访问这个方法,只有等待这个方法执行完毕或者代码块执行完毕,这个线程才会释放该对象的锁,其他线程才能执行这个方法或者代码块。
Synchronized锁又称对象监视器(Object)
2.Synchronized作用范围分析
- 修饰一个代码块,被修饰的代码叫做同步语块,其作用范围为{}部分,作用的对象是调用这个代码块的对象。
- 修饰一个方法,被修饰的方法叫做同步方法,其作用范围为整个方法,作用的对象是调用这个方法的对象。
- 修饰一个静态方法,其作用范围是整个静态方法,作用的对象是这个类的所有对象
- 修饰一个类,其作用方位是Synchronized{}中括起来的部分,作用的对象是这个类的所有对象
3.Synchronized作用范围例子
- synchronized修饰一个代码块
package com.tokyo.practice.syncronizedPractice.namespacePractice;
public class SyncCodeBlockDemo {
public static void main(String args[]) {
SyncCodeBlockTest SyncCodeBlockTest = new SyncCodeBlockTest();
for (int i = 0; i < 10; i++) {
CodeBlockSynchronized obj = new CodeBlockSynchronized(SyncCodeBlockTest);
obj.start();
}
}
}
class CodeBlockSynchronized extends Thread {
private SyncCodeBlockTest SyncCodeBlockTest;
CodeBlockSynchronized(SyncCodeBlockTest SyncCodeBlockTest) {
this.SyncCodeBlockTest = SyncCodeBlockTest;
}
@Override
public void run() {
SyncCodeBlockTest.test();
}
}
class SyncCodeBlockTest {
public void test() {
System.out.println(Thread.currentThread().getName());
synchronized(this) {
System.out.println(Thread.currentThread().getName() + "开始");
try {
Thread.sleep(1000);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName() + "结束");
}
}
}
输出:
Thread-0
Thread-1
Thread-0开始
Thread-2
Thread-3
Thread-4
Thread-5
Thread-6
Thread-7
Thread-8
Thread-9
Thread-0结束
Thread-9开始
Thread-9结束
Thread-8开始
Thread-8结束
Thread-7开始
Thread-7结束
Thread-6开始
Thread-6结束
Thread-5开始
Thread-5结束
Thread-4开始
Thread-4结束
Thread-3开始
Thread-3结束
Thread-2开始
Thread-2结束
Thread-1开始
Thread-1结束
4.Synchronized与ReentrantLock的区别?
synchronized是基于JVM实现的,Lock是基于Java编写的,主要通过硬件依赖CPU指令实现数据同步。
不同处:
- 等待可中断
在持有锁的线程长时间不释放锁的情况下,等待线程也可以选择等待 tryLock()
- 公平锁与非公平锁
synchroized实现的是非公平锁定,ReentrantLock可以通过构造函数实现公平锁public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}
- 多个condition条件
5.Synchronized字节码分析
package com.tokyo.practice.syncronizedPractice;
public class SynchronizedTest {
public static void main(String args[]) {
}
public void function() {
synchronized (this) {
}
}
}
操作:
➜ syncronizedPractice javac SynchronizedTest.java
➜ syncronizedPractice javap -c SynchronizedTest
获得的字节码:
Compiled from "SynchronizedTest.java"
public class com.tokyo.practice.syncronizedPractice.SynchronizedTest {
public com.tokyo.practice.syncronizedPractice.SynchronizedTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: return
public void function();
Code:
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_1
5: monitorexit
6: goto 14
9: astore_2
10: aload_1
11: monitorexit
12: aload_2
13: athrow
14: return
Exception table:
from to target type
4 6 9 any
9 12 9 any
}
其中字节码中包含monitorenter与monitorexit
网友评论