云时代架构阅读笔记七——Java多线程中如何使用synchronized关键字
关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。本文探讨synchronized关键字。
synchronized关键字可以修饰方法,可以修饰代码块,但不能修饰构造器、属性等。
对synchronized(this)的一些理解
- 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
- 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
- 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的除synchronized(this)同步代码块以外的部分。
- 第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
- 以上规则对其它对象锁同样适用。
一:synchronized同步代码块
public class SyncThread1 implements Runnable {
private Integer key = 0; @Override
public void run() {
// key是Integer对象(注意不是int,因为int不是对象)
// 线程进入下面同步代码之前,需要先获取key的锁。
// 需要结果是key实现自增长,如果没有同步块,则可能会出现重复key值的现象
synchronized (key) {
key++; System.out.println(Thread.currentThread().getName() + ":" + key);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
} public static void main(String[] args) {
SyncThread1 st = new SyncThread1(); for(int i=0; i<10; i++) {
new Thread(st, "Thread" + i).start();
}
}
}
输出:
Thread1:2
Thread3:3
Thread5:4
Thread7:5
Thread0:2
Thread2:7
Thread9:6
Thread4:8
Thread6:9
Thread8:10
二:synchronized同步方法
同步方法分静态和非静态两种。静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。
2.1 非静态方法同步示范
// 如果是同步方法,则分静态和非静态两种。
// 静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。
public class SyncThread2 implements Runnable {
private Integer key = 0; // 此示范为非静态方法同步
public synchronized Integer getKey() {
key++; return key;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + getKey());
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
} public static void main(String[] args) {
// 非静态方法同步,需要启动单例模式
SyncThread2 st = new SyncThread2();
for (int i = 0; i < 10; i++) {
new Thread(st, "Thread" + i).start();
}
}
}
输出:
Thread0:1
Thread1:3
Thread2:2
Thread3:5
Thread5:6
Thread7:7
Thread9:8
Thread6:9
Thread8:10
Thread4:4
2.2 静态方法同步示范
// 如果是同步方法,则分静态和非静态两种。
// 静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。
public class SyncThread3 implements Runnable {
private static Integer key = 0; // 此示范为静态方法同步
public synchronized static Integer getKey() {
key++; return key;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + getKey());
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
} public static void main(String[] args) { // 如果用静态方法实现同步,则可以生成对象的多个实例
for (int i = 0; i < 10; i++) {
SyncThread3 st = new SyncThread3();
new Thread(st, "Thread" + i).start();
}
}
}
输出:
Thread3:3
Thread1:1
Thread0:2
Thread5:4
Thread7:5
Thread9:6
Thread2:7
Thread8:10
Thread6:9
Thread4:8
总结
1、无论是同步代码块还是同步方法,必须获得对象锁才能够进入同步代码块或者同步方法进行操作。
2、如果采用方法级别的同步,对象锁为方法所在的对象;如果是静态同步方法,对象锁为方法所在的类(唯一)。
3、对于代码块,对象锁即指synchronized(object)中的object。
转自:https://www.cnblogs.com/nayitian/p/3258536.html
云时代架构阅读笔记七——Java多线程中如何使用synchronized关键字的更多相关文章
- 云时代架构阅读笔记六——Java内存模型详解(二)
承接上文:云时代架构阅读笔记五——Java内存模型详解(一) 原子性.可见性.有序性 Java内存模型围绕着并发过程中如何处理原子性.可见性和有序性这三个特征来建立的,来逐个看一下: 1.原子性(At ...
- 云时代架构阅读笔记一——Java性能优化(一)
Java语言学习了这么长时间之后,自己对于Java编程的一些细节还是稍微有点总结,正好根据云时代架构中<Java高级开发必会的50个性能优化的细节(珍藏版)>来叙述一些我和里面的点比较相符 ...
- 云时代架构阅读笔记二——Java性能优化(二)
承接上文Java性能优化(一)https://www.cnblogs.com/guo-xu/p/11019267.html 4)尽量确定StringBuffer的容量 在说和这个标题相关之前,先说一下 ...
- 云时代架构阅读笔记五——Java内存模型详解(一)
什么是Java内存模型 Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的访问差异,以实现让Java程序在各种平台下都能达到一致 ...
- 云时代架构阅读笔记十五——之前碰到的Java面试题
1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.Java有 ...
- 云时代架构阅读笔记十六——Hystrix理解
背景 分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务.如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服 ...
- 云时代架构阅读笔记十四——我对Hash算法的理解
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是 ...
- 云时代架构阅读笔记十一——数据库SQL优化
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 ...
- 云时代架构阅读笔记九——web应用存在的问题及解决办法
web应用通常存在的10大安全问题 1.SQL注入 拼接的SQL字符串改变了设计者原来的意图,执行了如泄露.改变数据等操作,甚至控制数据库服务器, SQL Injection与Command Inje ...
随机推荐
- 编写跨平台Java程序注意事项
使用Java语言编写应用程序最大的优点在于“一次编译,处处运行”,然而这并不是说所有的Java程序都具有跨平台的特性,事实上,相当一部分的Java程序是不能在别的操作系统上正确运行的,那么如何才能编写 ...
- 微信小程序 画布arc截取圆形图片
画布提供了一种可以创建圆的方法 arc(x, y, r, s, e, counterclockwise) x,y:圆心 r:圆的半径 s:起始弧度 (0) e:终止弧度 (1.5 * Math.PI) ...
- 彻底搞懂 JS 中 this 机制
彻底搞懂 JS 中 this 机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 目录 this 是什么 this 的四种绑定规 ...
- PHP 函数的作用
函数是为了封装方法,方便调用. 设计一个计算的代码函数.举个栗子 <?php /** * Created by PhpStorm. * User: 炜文 * Date: 2017/2/15 * ...
- IdentityServer4专题之二:OpenID介绍
1.基于概念 OpenId是一个以用户为中心的数字身份识别框架,它具有开放.分散.自由等特性.OpenId的创建是基于这样一个概念:我们可以通过URI(或者URL网址)来识别一个网站.同样,我们也可以 ...
- QAM格雷码映射的规则(Gray Code Mapping in QAM)
高阶调制(QAM,MQAM)信号中做基带映射,格雷码作为一种规范的映射规则,加上I,Q方向上相邻两个星座点对应的Bit_Cluster中只有一个Bit不同,所以有方便统一的特性. 以16QAM为例,先 ...
- Ubuntu 16.04非编译安装Zabbix 3.2----服务端和客户端win的配置
控服务器 - 什么是Zabbix Zabbix是企业级开源分布式监控服务器解决方案. 该软件监控网络的不同参数和服务器的完整性,还允许为任何事件配置基于电子邮件的警报. Zabbix根据存储在数据库( ...
- HiBench成长笔记——(4) HiBench测试Spark SQL
很多内容之前的博客已经提过,这里不再赘述,详细内容参照本系列前面的博客:https://www.cnblogs.com/ratels/p/10970905.html 和 https://www.cnb ...
- PhoneGap简易配置使用
在Android Studio 里新一下Android项目, 这个不用说了. 链接: https://pan.baidu.com/s/1qYcCBEW 密码: ymhh 添加 cordovaapp-c ...
- 谈谈HashSet的存储原理及为什么重写equals必须重写hashcode方法
HashSet的存储原理: 1.将要传入的数据根据系统的hash算法得到一个hash值: 2.根据hash值可以得出该数据在hash表中的位置: 3.判断该位置上是否有值,没有值则把数据插入进来:如果 ...