Java synchronized同步 各方式略解
近段为了实现一个功能,在树结构中,修改某个节点名称时,需要同时修改这个节点所有子节点的节点全路径属性字段(类似"父父节点名称/父节点名称/子节点名称/子子节点名称"的构造)。因为在构造Update语句时,需要递归去查询子节点以及构造全路径的值,需要花费了一定的时间,等批量执行update语句时,可能子节点的某个子节点的名称又改变了,会引起冲突,故用到了synchronized,顺便了解了下实现方式,原理没深入了解,在此记录以便日后查看。
-----------------------------------------------------我是正文分割线--------------------我是正文分割线---------------------------
本文主要列举不同的同步方式,以及我理解的使用范围。
众所周知,同步分为两种用法:同步方法、与同步块。
一、同步块
1.1 类同步(非静态方法)
· 实现方式:
public class JustPlayServiceImplSyn2 { public JustPlayServiceImplSyn2(){ }
private static int flag = 1;
public void operate() {
synchronized(JustPlayServiceImplSyn2.class){
flag++;
try {
// 增加随机性,让不同线程能在此交替执行
Thread.sleep(new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
}
flag--;
System.out.println("Thread: " + Thread.currentThread().getName()
+ " /Current flag: " + flag);
}
}
}
· 测试代码:
public class JustPlay {
/**
* @param args
*/
public static void main(String[] args) {
new Thread("Thread-01") {
public void run() {
new JustPlayServiceImplSyn2().operate();
}
}.start(); // 启动第一个线程 new Thread("Thread-02") {
public void run() {
new JustPlayServiceImplSyn2().operate();
}
}.start(); // 启动第一个线程
}
}
· 使用范围:多对象多线程的同步。
使用范围最广,代码也简单,在需要同步的代码块上加上synchronized关键字,并在括号类用[类名.class]就行。
1.2 this同步(非静态方法)
· 实现方式:
public class JustPlayServiceImplSyn2 { public JustPlayServiceImplSyn2(){ }
private static int flag = 1;
public void operate_this() {
synchronized(this){
flag++;
try {
// 增加随机性,让不同线程能在此交替执行
Thread.sleep(new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
}
flag--;
System.out.println("Thread: " + Thread.currentThread().getName()
+ " /Current flag: " + flag);
}
}
}
· 测试代码:
public class JustPlay { /**
* @param args
*/
public static void main(String[] args) {
final JustPlayServiceImplSyn2 justplayserviceimplsyn2= new JustPlayServiceImplSyn2();
for(int i=0;i<100;i++){
new Thread("Thread-001"){
public void run() {
justplayserviceimplsyn2.operate_this();
}
}.start();
new Thread("Thread-002"){
public void run() {
justplayserviceimplsyn2.operate_this();
}
}.start();
}
}
· 使用范围:单对象多线程的同步。
在synchronized关键字后的括号内用this关键字。使用[this]同步时需要是同一对象的才能同步,多对象时是同步失败的。因为同步是对this对象锁,不同对象时锁互不影响
1.3 静态对象同步(非静态方法)
· 实现方式:
public class JustPlayServiceImpl {
private static JustPlayServiceImpl myobj = null; private JustPlayServiceImpl(){ }
public static JustPlayServiceImpl createJustPlayServiceImpl(){
if(myobj==null){
myobj = new JustPlayServiceImpl();
}
return myobj;
}
private static int flag = 1;
public void operate() {
synchronized(myobj){
flag++;
try {
// 增加随机性,让不同线程能在此交替执行
Thread.sleep(new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
}
flag--;
System.out.println("Thread: " + Thread.currentThread().getName()
+ " /Current flag: " + flag);
}
}
}
· 测试代码:
1 public class JustPlay {
2
3 /**
4 * @param args
5 */
6 public static void main(String[] args) {
7
8 for(int i=0;i<100;i++){
9 new Thread("Thread-01") {
10 public void run() {
11 JustPlayServiceImpl.createJustPlayServiceImpl().operate()) }
12 }.start(); // 启动第一个线程
13 new Thread("Thread-02") {
14 public void run() {
15 JustPlayServiceImpl.createJustPlayServiceImpl().operate() }
16 }.start(); // 启动第二个线程
17 }
· 使用范围:单体类单对象多线程的同步。
因为同步是对对象的同步锁,只要保证同步块对象唯一,就能实现同步。偷点懒,我直接将类变成了单体类,然后将唯一对象给锁了。(ps:怎么感觉有点鬼畜。。。哈哈哈)
二、同步方法
2.1 静态方法同步
· 实现方式:
public class JustPlayServiceImplSyn2 { public JustPlayServiceImplSyn2(){ }
private static int flag = 1;
public synchronized static void operate_static(){
flag++;
try {
// 增加随机性,让不同线程能在此交替执行
Thread.sleep(new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
}
flag--;
System.out.println("Thread: " + Thread.currentThread().getName()
+ " /Current flag: " + flag);
}
}
· 测试代码:
public class JustPlay { /**
* @param args
*/
public static void main(String[] args) {
for(int i=0;i<100;i++){
new Thread("Thread-01") {
public void run() {
JustPlayServiceImplSyn2.operate_static();
}
}.start(); // 启动第一个线程 new Thread("Thread-02") {
public void run() {
JustPlayServiceImplSyn2.operate_static();
}
}.start(); // 启动第一个线程
}
}
}
· 使用范围:静态方法单对象多线程的同步。
再次说[因为同步是对对象的同步锁],而且调用静态方法绑定的是类而不是对象,所以,同步了静态方法,就是将相当于将类给锁了,然后就同步了。原理与[1.1 类同步(非静态方法)]一致。
2.2 非静态方法同步
2.2.1 单体类非静态方法同步
· 实现方式:
public class JustPlayServiceImpl {
private static JustPlayServiceImpl myobj = null; private JustPlayServiceImpl(){ }
public static JustPlayServiceImpl createJustPlayServiceImpl(){
if(myobj==null){
myobj = new JustPlayServiceImpl();
}
return myobj;
}
private static int flag = 1; //单体类 此种同步方式有效
public synchronized void operate2() {
flag++;
try {
// 增加随机性,让不同线程能在此交替执行
Thread.sleep(new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
}
flag--;
System.out.println("Thread: " + Thread.currentThread().getName()
+ " /Current flag: " + flag);
}
}
· 测试代码:
public static void main(String[] args) { for(int i=0;i<100;i++){
new Thread("Thread-01") {
public void run() {
JustPlayServiceImpl.createJustPlayServiceImpl().operate2();
}
}.start(); // 启动第一个线程 new Thread("Thread-02") {
public void run() {
JustPlayServiceImpl.createJustPlayServiceImpl().operate2();
}
}.start(); // 启动第一个线程
}
}
}
· 使用范围:单体类单对象多线程的同步。
原理同[1.3 静态对象同步(非静态方法)]
2.2.2 非单体类非静态方法同步
· 实现方式:
public class JustPlayServiceImplSyn2 { public JustPlayServiceImplSyn2(){ }
private static int flag = 1;
//适用于单对象多线程
public synchronized void operate2() {
flag++;
try {
// 增加随机性,让不同线程能在此交替执行
Thread.sleep(new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
}
flag--;
System.out.println("Thread: " + Thread.currentThread().getName()
+ " /Current flag: " + flag);
}
}
· 测试代码:
public class JustPlay { /**
* @param args
*/
public static void main(String[] args) {
final JustPlayServiceImplSyn2 justplayserviceimplsyn2= new JustPlayServiceImplSyn2();
for(int i=0;i<100;i++){
new Thread("Thread-001"){
public void run() {
justplayserviceimplsyn2.operate2();
}
}.start();
new Thread("Thread-002"){
public void run() {
justplayserviceimplsyn2.operate2();
}
}.start();
}
}
· 使用范围:单对象多线程的同步。
原理同[1.2 this同步(非静态方法)]
总结:对于网页用ajax方式多次调用的class,因为是多线程且不可控为单一对象,若想同步:解决方案是:1.1、1.3、2.1、2.2.1;对于1.2和2.2.2,调用的对象必须是保持同一个才会同步。
PS:觉得应该还有其他方式,隐隐的这么觉得。。。。。哈哈哈哈哈哈
------------------------------------结束的分割线--------------结束的分割线------------------有机会再去了解同步的底层原理去了----那时候再写原理------またね!---
Java synchronized同步 各方式略解的更多相关文章
- java synchronized 同步详解
记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...
- Java 多线程同步和异步详解
java线程 同步与异步 线程池 1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成 ...
- Java中String做为synchronized同步锁使用详解
Java中使用String作同步锁 在Java中String是一种特殊的类型存在,在jdk中String在创建后是共享常量池的,即使在jdk1.8之后实现有所不同,但是功能还是差不多的. 借助这个特点 ...
- Java线程同步的方式
java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的 ...
- Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。
精彩理解: https://www.jianshu.com/p/21be831e851e ; https://blog.csdn.net/heyutao007/article/details/19 ...
- Java线程同步的四种方式详解(建议收藏)
Java线程同步属于Java多线程与并发编程的核心点,需要重点掌握,下面我就来详解Java线程同步的4种主要的实现方式@mikechen 目录 什么是线程同步 线程同步的几种方式 1.使用sync ...
- java synchronized 线程同步机制详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
- 【转】线程同步------java synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
- java中同步(synchronized)详解
一.开山篇: 1.synchronized的使用 一个程序中,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题.在Java中内置了语言级的同步原语--synchronized,这也大大简 ...
随机推荐
- 百度地图自定义Marker
最近写了百度地图的Demo,所以总结下遇到的问题: 1.首先在百度地图中创建应用时用到 发布版SHA1是在Preferences下的Android下的Build中;2.在使用百度地图时,先要创建一个A ...
- Ibatis中常见错误解决方案
在Ibatis 的sqlMap或者sqlMapConfig配置文件中如果出现以下错误信息: Referenced file contains errors (http://www.ibatis.com ...
- springmvc(2)Controller源码简单解析
前面简单的分析了一下DispatcherServlet,接下来分析一下Controller,在web的MVC中,Controller就是其中的C,启动的一些页面逻辑处理,页面映射的功能: 首先看看超类 ...
- android 查找某个特定文件后缀名
private void queryFiles(){ String[] projection = new String[] { MediaStore.Files.FileColumns._ID, Me ...
- excel查看VBA代码快捷键
公司现在的很多自动化代码生成使用excel VBA,本来这事跟自己一点关系打不着,不过计划年底切换中间件,这得导致部分代码结构调整,自己还得去调整测试,老忘掉这快捷键,特记录下,Alt + F11
- [js开源组件开发]localStorage-cache本地存储的缓存管理
localStorage-cache本地存储的缓存管理 距离上次的组件开发有近三个月的时间了,最近一直在做一些杂事,无法静下心来写写代码,也是在学习emberjs,在emberjs中有一个很重要的东西 ...
- 百度的echart环形图颜色动态设置
自己参与的有一个项目需要用到环行图,考虑到百度的echart功能很强大兼容性又挺好就使用了这个插件,但是在颜色配置的时候出现了问题按照参考文档的方法是用color:Array这样的形式,但是不知道在哪 ...
- Office 365 - SharePoint 2013 Online之添加App开发工具Napa
1.新建一个网站集,模板选择开发人员模板,如下图: 2.确定以后,需要稍等一会儿; 3.点击网站内容,添加app,如下图: 4.进入SharePoint Store,选择Napa,如下图: 5.选择A ...
- 从angularJS看MVVM
javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力.我工作的业务不会涉及到angularJS[ng]这么重量级的 ...
- 什么是REST?
云计算的时代越来越多的提到一个词REST,那么什么是REST?如果你还不清楚,可以看这个视频和系列教程: http://www.restapitutorial.com/lessons/whatisre ...