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,这也大大简 ...
随机推荐
- Delphi 10.1 Berlin 官方未列之修正
Delphi 10.1 Berlin 官方修正列表: Bug fix list for RAD Studio 10.1 Berlin Delphi 10.1 Berlin 官方未列之修正: 修正 iO ...
- redis-desktop-manager
介绍一款Redis图形管理工具:redis-desktop-manager 下载地址:点击打开链接 我们打开redis-cl.exe 客户端,在里面添加了key= name ,value=heyang ...
- objective-c IOS应用更新
当前苹果已经禁止了,通过IOS应用直接跳转APP下载链接的方法.但是仍然可以使用另外一种方法直接跳转AppStore. 这种方法需要增加一个类库StoreKit.framework. 这里使用这功能是 ...
- objective-c高德地图时时定位
这篇随笔是对上一遍servlet接口的实现. 一.项目集成高德地图 应为我这个项目使用了cocopods这个第三方库管理工具,所以只需要很简单的步骤,就能将高德地图集成到项目中,如果你没使用过这工具, ...
- 应用服务器和Web服务器
如上图所示,绝大部分的公司会采用Apache+tomcat集群(或jetty集群)来部署公司的Web服务, Web服务器和应用服务器关系,先介绍一下我们常说的服务器: Tomcat服务器,是运行ser ...
- java 数据库连接池
1. About java利用jdbc直接连接数据库,经常取得连接,用完释放,很浪费系统资源 2. Code Java代码 package com.cdv.mam.db; import java.sq ...
- mysql定时任务简单例子
mysql定时任务简单例子 ? 1 2 3 4 5 6 7 8 9 如果要每30秒执行以下语句: [sql] update userinfo set endtime = now() WHE ...
- JAVA JDK的动态代理反射实现
动态代理类使用到了一个接口InvocationHandler和一个代理类Proxy ,这两个类配合使用实现了动态代理的功能. 什么是动态代理呢? 普通代理类是指: 给每个具体类写一个代理类,以后要使 ...
- JQuery(选择器、事件、DOM操作)
一.jQuery简介 jQuery 是一个 JavaScript 库. jQuery 极大地简化了 JavaScript 编程. jQuery 库位于一个 JavaScript 文件中,其中包含了所有 ...
- 今天做项目用到框架,关于angual,然后自己整理了一番,自己上网也看了看。
1. Angular 1.1. 库与框架的区别 jQuery:库 库一般都是封装了一些常用的方法 自己手动去调用这些方法,来完成我们的功能 $('#txt').val('我是小明'): $('div' ...