Synchronized小记

Synchronized小记

对Synchronized一直理解的比较恍惚,抽时间查阅了一下资料,并且经过例子验证,放在这里记录一下。

基本用法应该都知道。先上测试代码:

public class SynchronizedTest {

    private String lock = new String();

    public void syncClass() {
        synchronized (SynchronizedTest.class) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+ ": Sync class loop " + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void syncClassThis() {
        synchronized (SynchronizedTest.this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+ ": Sync class.this loop " + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void syncThis() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+ ": Sync this loop " + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void syncGlobalVar() {
        synchronized (lock) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+ ": Sync gloable variable loop " + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void syncLocalVar() {
        String flag = new String();
        synchronized (flag) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+ ": Sync local variable loop " + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public synchronized void syncMethod() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+ ": Sync method loop " + i);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static synchronized void syncStaticMethod() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+ ": Sync static method loop " + i);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

Main函数代码如下:

public static void main(String[] args) {
        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
//                a.syncClass();
//                a.syncClassThis();
//                a.syncThis();
//                a.syncGlobalVar();
//                a.syncLocalVar();
//                a.syncMethod();
//                a.syncStaticMethod();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
//                a.syncClass();
//                a.syncClassThis();
//                a.syncThis();
//                a.syncGlobalVar();
//                a.syncLocalVar();
//                a.syncMethod();
//                a.syncStaticMethod();
            }

        });
        t2.setName("B");
        t2.start();
    }

Part A

A1. Synchronized(ClassName.class)和Synchronized(ClassName.class)

执行代码如下:

public static void main(String[] args) {
        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncClass();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncClass();
            }

        });
        t2.setName("B");
        t2.start();
    }

执行结果如下:

A: Sync class loop 0
A: Sync class loop 1
A: Sync class loop 2
A: Sync class loop 3
A: Sync class loop 4
B: Sync class loop 0
B: Sync class loop 1
B: Sync class loop 2
B: Sync class loop 3
B: Sync class loop 4

分析:Synchronized(ClassName.class)将类的对象上锁。Class锁对类的所有对象实例起作用,多线程同步执行。

A2. Synchronized(ClassName.class)与Synchronized静态方法

执行代码如下:

public static void main(String[] args) {
        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncClass();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncStaticMethod();
            }

        });
        t2.setName("B");
        t2.start();
    }

执行结果如下:

A: Sync class loop 0
A: Sync class loop 1
A: Sync class loop 2
A: Sync class loop 3
A: Sync class loop 4
B: Sync static method loop 0
B: Sync static method loop 1
B: Sync static method loop 2
B: Sync static method loop 3
B: Sync static method loop 4

分析:synchronized static方法与synchronized(ClassName.class)代码块的作用一样。线程同步执行。

A3. Synchronized(ClassName.class)与其他

这里其他指的是:

  • a.syncClassThis() : synchronized (SynchronizedTest.this)
  • a.syncThis() : synchronized (this)
  • a.syncGlobalVar() : synchronized (lock) 全局变量lock
  • a.syncLocalVar() : synchronized (flag) 本地变量flag
  • a.syncMethod() : synchronized 非静态方法

其中一种执行结果:

A: Sync class loop 0
B: Sync method loop 0
B: Sync method loop 1
A: Sync class loop 1
A: Sync class loop 2
B: Sync method loop 2
B: Sync method loop 3
A: Sync class loop 3
A: Sync class loop 4
B: Sync method loop 4

我理解Synchronized(ClassName.class)与Synchronized静态方法是一个级别,对类的所有对象起作用,其他为一个级别。这两类别同用的时候,线程异步执行。

Part B

synchronized (ClassName.this)等同synchronized (this),在这里做一致处理。同步代码块,this是对用该方法的对象本身,而class是对该类本身。

B1. synchronized (this)与synchronized (this)

测试代码:

public static void main(String[] args) {

        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncThis();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncThis();
            }

        });
        t2.setName("B");
        t2.start();
    }

测试结果:

A: Sync this loop 0
A: Sync this loop 1
A: Sync this loop 2
A: Sync this loop 3
A: Sync this loop 4
B: Sync this loop 0
B: Sync this loop 1
B: Sync this loop 2
B: Sync this loop 3
B: Sync this loop 4

分析:当一个线程访问类的某个synchronized (this)同步代码块时,其它线程对同一个类中其它的synchronized (this)同步代码块的访问将是堵塞,这说明synchronized (this)使用的对象监视器是一个。

B2. synchronized (this)与synchronized 非静态方法

测试代码:

public static void main(String[] args) {

        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncThis();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncMethod();
            }

        });
        t2.setName("B");
        t2.start();
    }

测试结果:

A: Sync this loop 0
A: Sync this loop 1
A: Sync this loop 2
A: Sync this loop 3
A: Sync this loop 4
B: Sync method loop 0
B: Sync method loop 1
B: Sync method loop 2
B: Sync method loop 3
B: Sync method loop 4

分析:和B1一样,多个线程调用同一个对象中不同名称的synchronized同步非静态方法或者synchronized(this)同步代码块时,线程同步。

B3. synchronized (this)与synchronized 全局变量

测试代码:

public static void main(String[] args) {

        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncThis();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncGlobalVar();
            }

        });
        t2.setName("B");
        t2.start();
    }

结果(之一)如下:

A: Sync this loop 0
B: Sync gloable variable loop 0
A: Sync this loop 1
B: Sync gloable variable loop 1
A: Sync this loop 2
B: Sync gloable variable loop 2
B: Sync gloable variable loop 3
A: Sync this loop 3
A: Sync this loop 4
B: Sync gloable variable loop 4

this为调用syncThis()方法的对象实例,而syncGlobalVar()方法同步的是全局变量lock,互不影响,线程异步执行。

B4. synchronized (this)与synchronized 局部变量

测试代码:

public static void main(String[] args) {

        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncThis();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncLocalVar();
            }

        });
        t2.setName("B");
        t2.start();
    }

结果(之一)如下:

A: Sync this loop 0
B: Sync local variable loop 0
B: Sync local variable loop 1
A: Sync this loop 1
B: Sync local variable loop 2
A: Sync this loop 2
A: Sync this loop 3
B: Sync local variable loop 3
B: Sync local variable loop 4
A: Sync this loop 4

与B3一样,同步代码块分别锁定this实例和局部变量flag,互不干涉,线程异步。

B5. synchronized (this)与synchronized 静态方法

两个线程分别调用syncThis()方法和syncStaticMethod()方法。结果(之一)如下:

A: Sync this loop 0
B: Sync static method loop 0
A: Sync this loop 1
B: Sync static method loop 1
B: Sync static method loop 2
A: Sync this loop 2
A: Sync this loop 3
B: Sync static method loop 3
B: Sync static method loop 4
A: Sync this loop 4

分析:在A2中讲过,synchronized (ClassName.class)和synchronized 静态方法效果一样,属于同步类本身。互不影响,线程异步执行。

Part C

C1. Synchronized 全局变量和Synchronized 全局变量

测试代码:

public static void main(String[] args) {

        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncGlobalVar();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncGlobalVar();
            }

        });
        t2.setName("B");
        t2.start();
    }

测试结果:

A: Sync gloable variable loop 0
A: Sync gloable variable loop 1
A: Sync gloable variable loop 2
A: Sync gloable variable loop 3
A: Sync gloable variable loop 4
B: Sync gloable variable loop 0
B: Sync gloable variable loop 1
B: Sync gloable variable loop 2
B: Sync gloable variable loop 3
B: Sync gloable variable loop 4

分析:多个线程持有对象监视器作为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(任意自定义对象)同步代码快。

C2. Synchronized 全局变量和Synchronized 局部变量

测试代码:

public static void main(String[] args) {

        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncGlobalVar();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncLocalVar();
            }

        });
        t2.setName("B");
        t2.start();
    }

测试结果(之一):

A: Sync gloable variable loop 0
A: Sync gloable variable loop 1
B: Sync local variable loop 0
A: Sync gloable variable loop 2
A: Sync gloable variable loop 3
B: Sync local variable loop 1
A: Sync gloable variable loop 4
B: Sync local variable loop 2
B: Sync local variable loop 3
B: Sync local variable loop 4

两个线程同步的为不同变量,线程异步执行。

C3. Synchronized 全局变量和Synchronized 非静态方法

测试代码:

public static void main(String[] args) {

        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncGlobalVar();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncMethod();
            }

        });
        t2.setName("B");
        t2.start();
    }

测试结果(之一):

A: Sync gloable variable loop 0
B: Sync method loop 0
A: Sync gloable variable loop 1
B: Sync method loop 1
B: Sync method loop 2
A: Sync gloable variable loop 2
B: Sync method loop 3
A: Sync gloable variable loop 3
B: Sync method loop 4
A: Sync gloable variable loop 4

同步代码块对象为全局变量,另一方为调用同步非静态类方法的对象,互不干涉,线程异步执行。

Part D

D1. Synchronized 局部变量和Synchronized 局部变量

测试代码:

public static void main(String[] args) {

        final SynchronizedTest a = new SynchronizedTest();  

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncLocalVar();
            }

        });
        t1.setName("A");
        t1.start();

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                a.syncLocalVar();
            }

        });
        t2.setName("B");
        t2.start();
    }

测试结果(之一):

A: Sync local variable loop 0
B: Sync local variable loop 0
B: Sync local variable loop 1
A: Sync local variable loop 1
A: Sync local variable loop 2
B: Sync local variable loop 2
A: Sync local variable loop 3
B: Sync local variable loop 3
B: Sync local variable loop 4
A: Sync local variable loop 4

这个结果显而易见,线程异步。事实上,Synchronized 局部变量与其他任何同步方法或者同步代码块执行的时候,因为上锁的“对象”不同,线程之间都是异步执行的。

总结

Synchronized可以同步代码块和同步方法,同一个实例在进行多线程调用的时候,线程之间的执行结果如下表:

执行结果synchronized (ClassName.class)synchronized 静态方法synchronized (ClassName.this)synchronized (this)synchronized 非静态方法synchronized (全局变量)synchronized (局部变量)
synchronized (ClassName.class)同步同步异步异步异步异步异步
synchronized
静态方法
同步同步异步异步异步异步异步
synchronized (ClassName.this)异步异步同步同步同步异步异步
synchronized (this)异步异步同步同步同步异步异步
synchronized
非静态方法
异步异步同步同步同步异步异步
synchronized
(全局变量)
异步异步异步异步异步同步异步
synchronized
(局部变量)
异步异步异步异步异步异步异步
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值