synchronized的四种作用域以及不能被继承解析
synchronized
是java
中用于同步
的关键字,其典型的作用域如下所示.
1 对象锁
@Slf4j
public class SynchronizedExample1 {
private final int loopNum = 20;
// 修饰一个代码块
private void test1(int j) {
synchronized (this) {
for (int i = 0; i < loopNum; i++) {
log.info("test1 {} - {}", j, i);
}
}
}
// 修饰一个方法
private synchronized void test2(int num) {
for (int i = 0; i < loopNum; i++) {
log.info("test2 {} - {}", num, i);
}
}
public static void main(String[] args) {
SynchronizedExample1 example1 = new SynchronizedExample1();
SynchronizedExample1 example2 = new SynchronizedExample1();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test2(1);
});
executorService.execute(() -> {
example2.test2(2);
});
executorService.shutdown();
}
}
1.1 代码块修饰(对象)
此时,synchronized
用于保证test1
函数中的被synchronized
大括号包裹的代码同步执行.
synchronized
作用的对象为SynchronizedExample1
的对象实例,例如main
函数中的example1
以及example2
.
Tips:
1.example1
若在多个线程中被调用,其输出顺序将保证同步,按照1,2,3...19,20
的顺序执行.
2.若example1
与example2
均在多个线程中执行,则test1...
之间保持同步输出,test2...
之间保持同步输出,但是test1...
与test2...
之间输出不保证顺序.
1.2 非静态函数修饰
synchronized
添加于test2
函数声明中,其作用类似于1.1
中的代码块修饰,区别点仅仅在于
其同步代码块扩充至整个函数
(test2
).
2. 类锁
@Slf4j
public class SynchronizedExample2 {
private static final int loopNum = 20;
// 修饰一个类
private static void test1(int j) {
synchronized (SynchronizedExample2.class) {
for (int i = 0; i < loopNum; i++) {
log.info("test1 {} - {}", j, i);
}
}
}
// 修饰一个静态方法
private static synchronized void test2(int j) {
for (int i = 0; i < loopNum; i++) {
log.info("test2 {} - {}", j, i);
}
}
public static void main(String[] args) {
SynchronizedExample2 example1 = new SynchronizedExample2();
SynchronizedExample2 example2 = new SynchronizedExample2();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test1(1);
});
executorService.execute(() -> {
example2.test1(2);
});
}
}
2.1 代码块修饰(类)
与1.1
中区别在于,synchronized
函数修饰的是SynchronizedExample2
类.
SynchronizedExample2
对象,诸如example1
或者example2
在任意多的线程中调用test1
函数,其输出顺序均会被保证(1,2,3,4...19,20
).
2.2 静态函数修饰
功能与2.1
类似,均是对对象加锁,确保多个类对象调用函数时保持顺序.
Tips:
示例中,因为类上加锁的原因,test1
与test2
对象保持顺序执行,不会出现test1...
与test2...
交叉出现的现象.
3 synchronized
不能被继承
需要注意,若synchronized
修饰于函数中,如1.2
以及2.2
,若有类继承于SynchronizedExample1
或者SynchronizedExample1
,子类对象调用test2
不同步.
原因:synchronized
非函数签名,因此无法被继承,所以无法保证子类调用同步.
PS:
如果您觉得我的文章对您有帮助,可以扫码领取下红包,谢谢!
synchronized的四种作用域以及不能被继承解析的更多相关文章
- jsp九大内置对象、四种作用域、跳转方式
jsp有四种属性范围: page -> 页面级别,显然只有在一个页面内可用. request -> 请求级别 服务器跳转,一次请求之后消失. session -> 会话级别 客户端跳 ...
- Javaweb容器的四种作用域
几乎所有web应用容器都提供了四种类似Map的结构:application session request page,Jsp或者Servlet通过向着这四个对象放入数据,从而实现Jsp和Servlet ...
- scope的四种作用域的使用
如何使用spring的作用域: <bean id="role" class="spring.chapter2.maryGame.Role" scope=& ...
- 四种Java线程池用法解析
本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 执行一个异步任务你还只是如下 ...
- 面试题:四种Java线程池用法解析 !=!=未看
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? 1 2 3 4 5 6 7 8 new Thread(new Runnable() { @Override ...
- synchronized的四种用法
一 修饰方法 Synchronized修饰一个方法很简单,就是在方法的前面加synchronized,synchronized修饰方法和修饰一个代码块类似,只是作用范围不一样,修饰代码块是大括号括起 ...
- java synchronized的四种用法
一 修饰方法 Synchronized修饰一个方法很简单,就是在方法的前面加synchronized,synchronized修饰方法和修饰一个代码块类似,只是作用范围不一样,修饰代码块是大括号括起来 ...
- C和指针 第三章 四种作用域
代码块作用域: 任何位于一对花括号之间是一个代码块,代码块内声明的标识符具有代码块作用域,嵌套代码块内,内部变量会屏蔽外部相同标示的标示符,非嵌套代码块,不会同时处于活动状态所以不会屏蔽. int m ...
- JSP中的四种作用域?
page.request.session和application,具体如下: ①page 代表与一个页面相关的对象和属性. ②request 代表与Web客户机发出的一个请求相关的对象和属性.一个请求 ...
随机推荐
- JavaScript 设计模式之----单体(单例)模式
设计模式之--单体(单例)模式 1.介绍 从本章开始,我们会逐步介绍在JavaScript里使用的各种设计模式实现,在这里我不会过多地介绍模式本身的理论,而只会关注实现.OK,正式开始. 在传统开发工 ...
- authorizations.go
{ return nil, fmt.Errorf("invalid TTL %d (must be >0)", authState.TTL) } ...
- Angularjs interceptor
angularJs 请求过滤 新建一个服务, $HttpProvider 中有一个 interceptore 数组,所谓的拦截器就是一个注册到该数组的工厂,该工厂在app.config() 中注入, ...
- STM32基于固件库新建MDK工程模板(精简版)
上个博文理论讲解的东西太多,太复杂,这里把所有步骤全部贴出 1.新建一个工程文件夹LED 2.LED文件夹下建立如下文件夹 3.Project –>New Uvision Project 到US ...
- Android--app性能问题的总结(一)
一个应用程序的性能问题体现在很多方面,app的性能问题,很大程度上决定了使用app的用户量,如果正在使用app的过程中出现app崩溃.卡顿半天加载不出数据(跟网络也有一定的关系).用户请求事件半天获 ...
- Maven的安装步骤
1.确保jdk安装成功,注意在系统环境下,必须添加jdk的路径.2.将maven的路径配置在系统环境变量中.3.修改maven的默认路径,即:将config下的settings.xml文件中的目录节点 ...
- 将wiki人脸数据集中的图片按男女分类
import shutil f_in = 'D:/wiki_crop' # 读取文件中图片信息根据性别分类图片到对应目录中 dirroot = "D:/" f = open(dir ...
- TensorFlow之DNN(三):神经网络的正则化方法(Dropout、L2正则化、早停和数据增强)
这一篇博客整理用TensorFlow实现神经网络正则化的内容. 深层神经网络往往具有数十万乃至数百万的参数,可以进行非常复杂的特征变换,具有强大的学习能力,因此容易在训练集上过拟合.缓解神经网络的过拟 ...
- TypeScript 实现任务队列
业务中经常会有一些批量操作的任务,比如使用 JavaScript 预加载一组图片,批量上传一些资源.如果这些任务一次性启动,势必会消耗很多资源和带宽.理想的做法应该对这些任务进行限制,比如一次只跑几个 ...
- ASP.NET Core在CentOS上的最小化部署实践
引言 本文从Linux小白的视角, 在CentOS 7.x服务器上搭建一个Nginx-Powered AspNet Core Web准生产应用. 在开始之前,我们还是重温一下部署原理,正 ...