博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java synchronized解析
阅读量:6962 次
发布时间:2019-06-27

本文共 5218 字,大约阅读时间需要 17 分钟。

多线程三大特性:

可见性、原子性、有序性

synchronize的特性:

1、同一时刻只有一个线程访问临界资源

2、其它未获取到锁执行权的线程必须排队等待

3、保证共享资源的原子性、可见性和有序性

4、进入synchronized范围内自动加锁,synchronized作用域外锁自动消除,即使异常也会释放锁

 synchronize加锁的方式:

  • 对于普通同步方法,锁是当前实例对象。

  • 对于静态同步方法,锁是当前类的Class对象。

  • 对于同步方法块,锁是Synchonized括号里配置的对象。

 

通过具体的例子来看一下

首先是普通方法:

class NoSyncTest {        public void method1() {            Log.i("sync", "method 1 start");            try {                Log.i("sync", "method 1 execute");                Thread.sleep(3000);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            Log.i("sync", "method 1 end");        }        public void method2() {            Log.i("sync", "method 2 start");            try {                Log.i("sync", "method 2 execute");                Thread.sleep(500);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            Log.i("sync", "method 2 end");        }    }    private void noSyncTest() {        final NoSyncTest test = new NoSyncTest();        Thread thread1 = new Thread(new Runnable() {            @Override            public void run() {                test.method1();            }        });        Thread thread2 = new Thread(new Runnable() {            @Override            public void run() {                test.method2();            }        });        thread1.start();        thread2.start();    }

这是一个没有任何同步的方法,NoSyncTest这个类有两个方法method1和method2,分别执行睡3s和0.5s的动作,然后再两个线程中分别调用这个类的实例test的两个方法,看一下结果:

 

可以看到method2和method1同时执行,method2因为sleep的时间短所以先结束。

再看一下普通方法同步:

class MethodSyncTest {        public synchronized void method1() {            Log.i("sync", "method 1 start");            try {                Log.i("sync", "method 1 execute");                Thread.sleep(3000);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            Log.i("sync", "method 1 end");        }        public synchronized void method2() {            Log.i("sync", "method 2 start");            try {                Log.i("sync", "method 2 execute");                Thread.sleep(500);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            Log.i("sync", "method 2 end");        }    }    private void MethodSyncTest() {        final MethodSyncTest test = new MethodSyncTest();        Thread thread1 = new Thread(new Runnable() {            @Override            public void run() {                test.method1();            }        });        Thread thread2 = new Thread(new Runnable() {            @Override            public void run() {                test.method2();            }        });        thread1.start();        thread2.start();

synchronize修饰的method1和method2,其他不变,看一下结果:

method1先执行然后3s之后结束了method2才开始执行。(注意这个地方不能new 不同的对象来调用方法,因为修饰普通方法本质是对对象的同步加锁。

看一下第三种静态同步方法:

static class StaticMethodSyncTest {        public static synchronized void method1() {            Log.i("sync", "method 1 start");            try {                Log.i("sync", "method 1 execute");                Thread.sleep(3000);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            Log.i("sync", "method 1 end");        }        public static synchronized void method2() {            Log.i("sync", "method 2 start");            try {                Log.i("sync", "method 2 execute");                Thread.sleep(500);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            Log.i("sync", "method 2 end");        }        public static synchronized void method3() {            Log.i("sync", "method 3 start");            try {                Log.i("sync", "method 3 execute");                Thread.sleep(1000);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            Log.i("sync", "method 3 end");        }    }    private void StaticMethodSyncTest() {        final StaticMethodSyncTest test1 = new StaticMethodSyncTest();        final StaticMethodSyncTest test2 = new StaticMethodSyncTest();        Thread thread1 = new Thread(new Runnable() {            @Override            public void run() {                test1.method1();            }        });        Thread thread2 = new Thread(new Runnable() {            @Override            public void run() {                test2.method2();            }        });        Thread thread3 = new Thread(new Runnable() {            @Override            public void run() {                StaticMethodSyncTest.method3();            }        });        thread1.start();        thread2.start();        thread3.start();    }

static修饰方法相当于这个方法是类方法,可以直接通过类名.方法名调用。我们在这new出了test1和test2两个对象分别调用method1和method2,以及通过类名.方法名调用method3,看一下结果

method1、method2、method3顺序执行。(同步静态方法的本质是锁的当前类

转载于:https://www.cnblogs.com/hxchaoshuai/p/9803160.html

你可能感兴趣的文章
exsi6.0远程修改密码
查看>>
Header和Cookie相关内容
查看>>
20个可能你不知道Linux网路工具
查看>>
Android 关于listView 显示不全的问题
查看>>
构造函数创建私有变量(防继承)
查看>>
scrum 开发方式学习笔记
查看>>
Terraform使用案例
查看>>
换个姿势学数学:学的爽,用的上
查看>>
Laravel 编码实践分享
查看>>
Mac下brew方式安装mysql
查看>>
开源的任务队列服务HTQ
查看>>
通过微信小程序看前端
查看>>
[LeetCode] Rotate Function
查看>>
iOS - 更轻量级的 AppDelegate - 面向服务设计
查看>>
什么样的爬虫才是好爬虫:Robots协议探究
查看>>
CentOS6.6设置静态ip
查看>>
tomcat 部署多个项目的技巧
查看>>
yii2使用多个数据库的案例
查看>>
[LintCode/LeetCode] Search Insert Position
查看>>
Node处理http跨域请求
查看>>