java中synchronized修饰的同步锁范围

本文围绕Java中synchronized的使用及范围展开,通过多个实例分别分析了对象锁和类锁。对象锁锁定当前对象,类锁可通过静态方法或代码块实现,二者都能实现线程同步。还指出对象锁和类锁相互独立,分别锁定当前对象和整个类。

Java中synchronized可以在多线程下做线程安全的同步锁,本文针对synchronized的使用及使用范围进行实例讨论

下面分别就对象锁和类锁进行分析

对象锁

非静态方法使用synchronized修饰的写法,锁定的是当前对象,例如

实例一:

public class Sync {
    private static final String TAG = "Sync";
    public synchronized void test1() {
            Log.e(TAG, "test1 start");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.e(TAG, "test1 end");
    }

    public synchronized void test2() {
        Log.e(TAG,"test2 start");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.e(TAG,"test2 end");
    }

}
public class ThreadDemo4Activity extends Activity {
    private static final String TAG = "ThreadDemo2Activity";
    Sync sync;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo3_ui);
        sync = new Sync();
        Thread2 thread2= new Thread2();
        thread2.start();
        Thread3 thread3= new Thread3();
        thread3.start();

    }

    class  Thread2 extends Thread{

        @Override
        public void run() {
            sync.test1();
        }
    }

    class  Thread3 extends Thread{

        @Override
        public void run() {
             sync.test2();
        }
    }




}

其打印结果如下:
07-09 15:39:30.073 24633-25111/com.yang.test E/Sync: test1 start
07-09 15:39:32.073 24633-25111/com.yang.test E/Sync: test1 end
07-09 15:39:32.074 24633-25112/com.yang.test E/Sync: test2 start
07-09 15:39:33.075 24633-25112/com.yang.test E/Sync: test2 end

实例一总结,一个类中有两个方法,两个方法都加了synchronized修饰,开两个线程分别调用同对象的两个方法,经过测试,打印出的Log,可以看到一个方法调用了,该对象的其他同步的方法就锁定了,等到该方法执行结束,才释放该对象其他的同步方法的锁。

实例二:

public class Sync {
    private static final String TAG = "Sync";
    public synchronized void test1() {
            Log.e(TAG, "test1 start");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.e(TAG, "test1 end");
    }

    public  void test2() {
        Log.e(TAG,"test2 start");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.e(TAG,"test2 end");
    }

}

执行结果:
07-09 15:47:00.099 25633-25730/com.yang.test E/Sync: test1 start
07-09 15:47:00.100 25633-25731/com.yang.test E/Sync: test2 start
07-09 15:47:01.101 25633-25731/com.yang.test E/Sync: test2 end
07-09 15:47:02.100 25633-25730/com.yang.test E/Sync: test1 end

实例二总结:相同的类,两个方法,一个加了synchronized同步锁,一个没加synchronized同步锁,开两个线程分别调用同一对象的两个方法,打印的Log可以看出,当调用了该对象的同步方法,并未锁定该对象的非同步的方法。

类锁

类锁有两种方法:一种是写在某个类里面的静态方法上或者使用在代码块上,例如:

实例三静态方法 :

 public static synchronized void test2() {
            Log.e(TAG,"Sync2 test start");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.e(TAG,"Sync2 test end");
    }

调用

package com.yang.test.demo3;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;

import com.yang.test.R;

public class ThreadDemo3Activity extends Activity {
    private static final String TAG = "ThreadDemo3Activity";
    Sync2 sync;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo3_ui);
        /*sync = new Sync2();
        for(int i=0;i<2;i++){
            Thread1 thread1 = new Thread1(sync);
            thread1.start();
        }*/

        sync = new Sync2();
        for(int i=0;i<2;i++){
            Thread2 thread2 = new Thread2(sync);
            thread2.start();
        }

    }

    class  Thread1 extends Thread{
        Sync2 sync ;

        public Thread1(Sync2 sync) {
            this.sync = sync;
        }

        @Override
        public void run() {
            sync.test1();
        }
    }

    class  Thread2 extends Thread{
        Sync2 sync ;

        public Thread2(Sync2 sync) {
            this.sync = sync;
        }

        @Override
        public void run() {
            sync.test2();
        }
    }

}

运行结果:

07-09 16:01:32.836 26679-26747/com.yang.test E/Sync2: Sync2 test start
07-09 16:01:34.837 26679-26747/com.yang.test E/Sync2: Sync2 test end
07-09 16:01:34.838 26679-26746/com.yang.test E/Sync2: Sync2 test start
07-09 16:01:36.839 26679-26746/com.yang.test E/Sync2: Sync2 test end

实例四代码块上:

 public void test1() {
        synchronized (Sync2.class) {
           Log.e(TAG,"Sync2 test start");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.e(TAG,"Sync2 test end");
        }
    }

调用:

package com.yang.test.demo3;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;

import com.yang.test.R;

public class ThreadDemo3Activity extends Activity {
    private static final String TAG = "ThreadDemo3Activity";
    Sync2 sync;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo3_ui);
        sync = new Sync2();
        for(int i=0;i<2;i++){
            Thread1 thread1 = new Thread1(sync);
            thread1.start();
        }

       /* sync = new Sync2();
        for(int i=0;i<2;i++){
            Thread2 thread2 = new Thread2(sync);
            thread2.start();
        }*/

    }

    class  Thread1 extends Thread{
        Sync2 sync ;

        public Thread1(Sync2 sync) {
            this.sync = sync;
        }

        @Override
        public void run() {
            sync.test1();
        }
    }

    class  Thread2 extends Thread{
        Sync2 sync ;

        public Thread2(Sync2 sync) {
            this.sync = sync;
        }

        @Override
        public void run() {
            sync.test2();
        }
    }

}

运行结果如下:

07-09 16:05:25.588 26990-27123/com.yang.test E/Sync2: Sync2 test start
07-09 16:05:27.589 26990-27123/com.yang.test E/Sync2: Sync2 test end
07-09 16:05:27.589 26990-27122/com.yang.test E/Sync2: Sync2 test start
07-09 16:05:29.589 26990-27122/com.yang.test E/Sync2: Sync2 test end

类锁总结:实例三和实例四,静态类和代码块,锁定类和对象锁很类似,都能达到线程同步的效果

 

下面我们再来测试一个案例:

同一个类中,一个方法是静态同步方法,一个是非静态同步方法,看看效果如何呢?

案例五:

package com.yang.test.demo3;

import android.util.Log;

public class Sync3 {
    private static final String TAG = "Sync1";
    public static synchronized void test1() {
            Log.e(TAG, "test1 start");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.e(TAG, "test1 end");
    }

    public synchronized void test2() {
        Log.e(TAG,"test2 start");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.e(TAG,"test2 end");
    }

}

调用:

package com.yang.test.demo3;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;

import com.yang.test.R;

public class ThreadDemo5Activity extends Activity {
    private static final String TAG = "ThreadDemo2Activity";
    Sync1 sync;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo3_ui);
        sync = new Sync1();
        Thread2 thread2= new Thread2();
        thread2.start();
        Thread3 thread3= new Thread3();
        thread3.start();

    }

    class  Thread2 extends Thread{

        @Override
        public void run() {
            Sync3.test1();
        }
    }

    class  Thread3 extends Thread{

        @Override
        public void run() {
            sync.test2();
        }
    }

}

其运行结果如下:

07-09 16:14:31.716 27597-27629/com.yang.test E/Sync1: test1 start
07-09 16:14:31.718 27597-27630/com.yang.test E/Sync1: test2 start
07-09 16:14:32.719 27597-27630/com.yang.test E/Sync1: test2 end
07-09 16:14:33.717 27597-27629/com.yang.test E/Sync1: test1 end

 

对象锁和类锁区别:

1、对象锁和类锁是相互独立的,互补干扰

2、对象锁锁定当前对象,类锁锁定整个类

3、一个类中两个方法,一个静态方法,一个非静态方法,都加了synchronized,静态方法为类锁,非静态方法为对象锁

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值