Synchronized小记

来源:互联网 发布:全国淘宝店铺有多少个 编辑:程序博客网 时间:2024/06/08 09:06

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
(局部变量) 异步 异步 异步 异步 异步 异步 异步
原创粉丝点击