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,这也大大简 ...
随机推荐
- iOS6.0下获取通讯录用户列表
自iOS6.0后获取通讯录列表需要询问用户,经过用户同意后才可以获取通讯录用户列表.而且ABAddressBookRef的初始化工作也由ABAddressBookCreate函数转变为ABAddres ...
- mysql笔记第三天
一下午在学习mysql,最有价值的就是这一点点 Order by 可以对在select字句中出现的字段位置进行排列eg:select name,count(*) from eg group by na ...
- 2016 年青岛网络赛---Family View(AC自动机)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5880 Problem Description Steam is a digital distribut ...
- 2015暑假多校联合---Zero Escape(变化的01背包)
题目链接 http://acm.hust.edu.cn/vjudge/contest/130883#problem/C Problem Description Zero Escape, is a vi ...
- ActiveMQ消息队列介绍
ActiveMQ是一个开源兼容Java Message Service (JMS) 1.1面向消息的中件间. 来自Apache Software Foundation. ActiveMQ提供松耦合 ...
- quartz TRIGGER_STATE变为ERROR解决方法
今天,项目组一个同事说开发环境一直正常quartz定时任务今天不跑了,因为异常已经封装了,所以应该不是没有捕获异常导致.也检查了JobDetail肯定没有重复的任务,最后检查qrtz_triggers ...
- 硬盘空间满导致mysql ibd文件被删后提示Tablespace is missing for table 'db_rsk/XXX"
昨天一早,开发人员反馈说一个测试环境报Tablespace is missing for table 'db_rsk/XXX",周末刚升级过,特地让开发回去查了下,说脚本中肯定没有drop ...
- Date类型 方法
Date 方法函数 Date.parse():可以获得该日期的毫秒数 var now=Date.parse('May 25,2005')//1085414400000 Date.UTC():也可以获得 ...
- ProgressBar.js – 漂亮的响应式 SVG 进度条
ProgressBar.js 是一个借助动态 SVG 路径的漂亮的,响应式的进度条效果.使用 ProgressBar.js 可以很容易地创建任意形状的进度条.这个 JavaScript 库提供线条,圆 ...
- jquery实现输入框实时输入触发事件代码
$('.aa').bind('input propertychange', function() { searchProductClassbyName(); }); function searchPr ...