原创

Java synchronize详解

1. synchronize关键字介绍

1.synchronized是Java中的关键字,是一种同步锁,使用方式如下

  1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象(锁的是synchronized括号里面的对象)
  2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象(锁的是当前实例对象)
  3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象(锁的是当前类的Class对象)
  4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象

2.synchronized修饰代码块

public class A implements Runnable{
    public static void main(String[] args) {
        A a = new A();
        Thread t1 = new Thread(a, "thread1");
        Thread t2 = new Thread(a, "thread2");
        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        aaa();
        synchronized(this) {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + ":" + (i++));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void aaa(){
        System.out.println(Thread.currentThread().getName()+"执行了aaaa方法");
    }
}

执行的结果

thread1执行了aaaa方法
thread2执行了aaaa方法
thread1:0
thread1:2
thread1:4
thread2:0
thread2:2
thread2:4

结论
1.一个线程访问一个对象A中的synchronized修饰的代码块时,其他线程试图访问该对象A中代码块的线程将被阻塞
2.一个线程访问一个对象A中的synchronized修饰的代码块时,不会阻塞其他线程访问该对象A中的方法,包括synchronized修饰的代码块所在的方法

假如其中main方法改为如下

public class A implements Runnable{
    public static void main(String[] args) {
        A a = new A();
        A b = new A();
        Thread t1 = new Thread(a, "thread1");
        Thread t2 = new Thread(b, "thread2");
        t1.start();
        t2.start();
    }
}

执行结果

thread1执行了aaaa方法
thread2执行了aaaa方法
thread1:0
thread2:0
thread1:2
thread2:2
thread1:4
thread2:4

3.2个线程访问的对象并非同一个对象则互不影响不会阻塞,因为每个对象只有一个锁(lock)与之相关联,synchronized锁的是对象,这时会有两把锁分别锁定a对象和b对象,而这两把锁是互不干扰,不形成互斥

3.synchronized修饰方法

正文到此结束
本文目录