Java基础-Synchronized详解一

2018-08-08  本文已影响0人  IBuddha

Java中的Synchronized详解

1.Synchronized简介

Synchronized简称同步锁。 在Java语言中,使用synchronized关键字来标记一个方法或者代码块,当某个线程调用该对象的synchronized方法或者访问synchronized代码块时,这个线程便获得了该对象的锁,其他线程暂时无法访问这个方法,只有等待这个方法执行完毕或者代码块执行完毕,这个线程才会释放该对象的锁,其他线程才能执行这个方法或者代码块。

Synchronized锁又称对象监视器(Object)

2.Synchronized作用范围分析

  1. 修饰一个代码块,被修饰的代码叫做同步语块,其作用范围为{}部分,作用的对象是调用这个代码块的对象。
  2. 修饰一个方法,被修饰的方法叫做同步方法,其作用范围为整个方法,作用的对象是调用这个方法的对象。
  3. 修饰一个静态方法,其作用范围是整个静态方法,作用的对象是这个类的所有对象
  4. 修饰一个类,其作用方位是Synchronized{}中括起来的部分,作用的对象是这个类的所有对象

3.Synchronized作用范围例子

  1. 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指令实现数据同步。

不同处:
  1. 等待可中断
    在持有锁的线程长时间不释放锁的情况下,等待线程也可以选择等待 tryLock()
  2. 公平锁与非公平锁
    synchroized实现的是非公平锁定,ReentrantLock可以通过构造函数实现公平锁public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}
  3. 多个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

上一篇下一篇

猜你喜欢

热点阅读