近段为了实现一个功能,在树结构中,修改某个节点名称时,需要同时修改这个节点所有子节点的节点全路径属性字段(类似"父父节点名称/父节点名称/子节点名称/子子节点名称"的构造)。因为在构造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同步 各方式略解的更多相关文章

  1. java synchronized 同步详解

    记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...

  2. Java 多线程同步和异步详解

    java线程 同步与异步 线程池 1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成 ...

  3. Java中String做为synchronized同步锁使用详解

    Java中使用String作同步锁 在Java中String是一种特殊的类型存在,在jdk中String在创建后是共享常量池的,即使在jdk1.8之后实现有所不同,但是功能还是差不多的. 借助这个特点 ...

  4. Java线程同步的方式

     java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),      将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的 ...

  5. Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。

    精彩理解:  https://www.jianshu.com/p/21be831e851e ;  https://blog.csdn.net/heyutao007/article/details/19 ...

  6. Java线程同步的四种方式详解(建议收藏)

    ​ Java线程同步属于Java多线程与并发编程的核心点,需要重点掌握,下面我就来详解Java线程同步的4种主要的实现方式@mikechen 目录 什么是线程同步 线程同步的几种方式 1.使用sync ...

  7. java synchronized 线程同步机制详解

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...

  8. 【转】线程同步------java synchronized详解

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...

  9. java中同步(synchronized)详解

    一.开山篇: 1.synchronized的使用 一个程序中,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题.在Java中内置了语言级的同步原语--synchronized,这也大大简 ...

随机推荐

  1. Junit很少出现的一个问题 No tests found matching ...

    java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=test2], {ExactMatcher:fDisp ...

  2. No.018:4Sum

    问题: Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...

  3. MAC 卸载 mysql

    怎样才能完全卸载mysql和删除它从你的Mac(包括所有数据库)执行以下操作: 打开终端窗口 使用mysqldump备份你的数据库将文本文件! 停止数据库服务器 sudo rm /usr/local/ ...

  4. [翻译] Autofac 中注册的概念

    原文链接:http://docs.autofac.org/en/latest/register/registration.html 所谓注册组件,是指创建 ContainerBuilder 的实例,并 ...

  5. jQuery Layer mobile 弹出层

    layer mobile是为移动设备(手机.平板等webkit内核浏览器/webview)量身定做的弹层支撑,采用Native JavaScript编写,完全独立于PC版的layer,您需要按照场景选 ...

  6. ZOOM - 简单易用的 jQuery 照片相册插件

    jQuery 最令人印象深刻的应用之一就是对图片的处理,它可以让帮助你在你的项目中加入一些让人惊叹的图片切换效果.ZOOM 是一款全屏效果的 jQuery 图片切换展示插件,支持键盘前后按键切换,支持 ...

  7. [deviceone开发]-echart的简单报表示例

    一.简介 echart是一个常用的基于h5的报表库.这个例子简单展示了实现折线图,柱状图,圆环图和圆饼图的使用. 并实现和do的非html部分的数据交互. 二.效果图 三.相关下载 https://g ...

  8. 刀锋上前行!绕过Ramint蠕虫病毒直接脱壳

    系统 : Windows xp 程序 : 某游戏客户端 程序下载地址 :不提供 要求 : 脱去压缩壳 使用工具 : OD & PEID & LordPE & Import RE ...

  9. Android 沉浸式状态栏 实现方式二 ( 更简单 )

    以前写过一个沉浸式状态栏 的实现方式 Android 沉浸式状态栏 实现方式一 现在有个更为简单的实现方式 . 相关链接 http://www.apkbus.com/forum.php?mod=vie ...

  10. Net.Sf.Json java Object to JsonObject

    public class People{ private String name; public void setName(String name){ this.name = name; } publ ...