标签存档: synchronized

java中的synchronized实践

第一种写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class SyncTest {
    public synchronized void synMethod1(String key) {  //  (*)
        System.out.println(key + " ==> " + Thread.currentThread().toString());
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        final SyncTest st1 = new SyncTest();
        Thread a1 = new Thread(new Runnable() {
            @Override
            public void run() {
                st1.synMethod1("No.1");
            }
        });
        a1.start();
        Thread a2 = new Thread(new Runnable() {
            @Override
            public void run() {
                st1.synMethod1("No.2");
            }
        });
        a2.start();
    }
}

输出为:

No.1 ==> Thread[Thread-0,5,main]

去除synchronized关键字,输出变为:

No.1 ==> Thread[Thread-0,5,main]
No.2 ==> Thread[Thread-1,5,main]

说明:标为synchronized的方法,进入后会把本对象锁住,其他线程无法进入任何非静态synchronized区域。

第二种写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class SyncTest {
    public void synMethod2(String key, Object lock) {
        System.out.println(key + " ==> I'm In. ");
        synchronized (lock) {  // (*)
            try {
                System.out.println(key + " ==> " + Thread.currentThread().toString());
                Thread.sleep(Long.MAX_VALUE);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        final SyncTest st1 = new SyncTest();
        final Object lock = new Object();   // (*)
        Thread a1 = new Thread(new Runnable() {
            @Override
            public void run() {
                st1.synMethod2("No.1", lock);
            }
        });
        a1.start();
        Thread a2 = new Thread(new Runnable() {
            @Override
            public void run() {
                st1.synMethod2("No.2", lock);
            }
        });
        a2.start();
    }
}

输出为:

No.1 ==> I'm In.
No.1 ==> Thread[Thread-0,5,main]
No.2 ==> I'm In.

修改synchronized(lock)为synchronized(key),输出变为:

No.1 ==> I'm In.
No.1 ==> Thread[Thread-0,5,main]
No.2 ==> I'm In.
No.2 ==> Thread[Thread-1,5,main]

说明:标为synchronized(object)的块,当object一样时,只有一个线程能够进入。

第三种写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class SyncTest {
    public void synMethod3(String key) {
        System.out.println(key + " ==> I'm In. ");
        synchronized (this) {  // (*)
            try {
                System.out.println(key + " ==> " + Thread.currentThread().toString());
                Thread.sleep(Long.MAX_VALUE);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        final SyncTest st1 = new SyncTest();
        Thread a1 = new Thread(new Runnable() {
            @Override
            public void run() {
                st1.synMethod3("No.1");
            }
        });
        final SyncTest st2 = new SyncTest();
        a1.start();
        Thread a2 = new Thread(new Runnable() {
            @Override
            public void run() {
                st1.synMethod3("No.2");   // (*)
            }
        });
        a2.start();
    }
}

输出为:

No.1 ==> I'm In.
No.1 ==> Thread[Thread-0,5,main]
No.2 ==> I'm In.

修改第26行的st1为st2,输出变为:

No.1 ==> I'm In.
No.1 ==> Thread[Thread-0,5,main]
No.2 ==> I'm In.
No.2 ==> Thread[Thread-1,5,main]

说明:
1、synchronized(this)其实就是synchronized(Object),只不过object传入了自己。
2、第一种写法中,对方法的synchronized声明,实际上等于对方法中所有代码的synchronized(this){}包裹。

第四种写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class SyncTest {
    public static String SSS = "static access";  // (*)
    public static void synMethod4(String key) {
        System.out.println(key + " ==> I'm In. ");
        synchronized (SyncTest.class) {  // (*)
            try {
                System.out.println(key + " ==> " + Thread.currentThread().toString());
                Thread.sleep(Long.MAX_VALUE);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public synchronized static void synMethod5(String key) {    // (*)
        System.out.println(key + " ==> I'm In synMethod5. ");
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws Exception {
        Thread a1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("No.1 ==> " + SyncTest.SSS);
                SyncTest.synMethod4("No.1");    // (*)
            }
        });
        a1.start();
        Thread a2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("No.2 ==> " + SyncTest.SSS);
                SyncTest.synMethod5("No.2");    // (*)
            }
        });
        Thread.sleep(1000);
        a2.start();
    }
}
 
<strong>输出为:</strong>
No.1 ==> static access
No.1 ==> I'm In.
No.1 ==> Thread[Thread-0,5,main]
No.2 ==> static access

将22行和30行的4和5对换,输出变为:

No.1 ==> static access
No.1 ==> I'm In synMethod5.
No.2 ==> static access
No.2 ==> I'm In.

说明:
1、类中synchronized(clasz)块的锁,可以阻止static方法的访问,但不影响static feild变量的访问。
2、类中static synchronized方法的锁,也会影响synchronized(clasz)块

纯属实验,若有错误,欢迎指正。

无觅相关文章插件,快速提升流量