java深入理解this,深入理解Java并发synchronized同步化的代码块不是this对象时的操作...

本文仅仅是为了说明synchronized关键字同步的是对象不是方法,列子的确有失偏颇。

一.明确一点synchronized同步的是对象不是方法也不是代码块

只要明确了synchronized同步的是对象那么,底下的问题就好解决了。

二.问题的导入

首先我有一个班级,班级中有学生。那么我们可以这样来模拟这个问题,代码如下:

import java.util.ArrayList;

public class Class {

//班级类

ArrayList students;

public Class(ArrayList students){

this.students=students;

}

}

//学生类

class Student{

private String name;

private int ID;

public Student(String name,int ID){

this.ID=ID;

this.name=name;

}

}

然后我们有一个班级事务处理类,来处理事务,这个类继承了Thread类代码入下:

import java.util.ArrayList;

import java.util.Arrays;

public class ClassText extends Thread{//班级事务处理类

Class class1;//待处理事务的班级

//构造器

public ClassText(Class class1){

this.class1=class1;

}

@Override//没有同步run方法

public void run(){

super.run();

addStudent(new Student("张三",15));

}

//添加学生,没有同步该方法

public void addStudent(Student student){

System.out.println("添加前现在有"+class1.students.size()+"个学生");

class1.students.add(student);

System.out.println("添加后现在有"+class1.students.size()+"个学生");

}

public static void main(String[] args) {

Class c=new Class(new ArrayList<>(Arrays.asList(new Student("李四",20),new Student("赵牛",20))));

ClassText ct1=new ClassText(c);

ClassText ct2=new ClassText(c);

ct1.start();

ct2.start();

}

}

显然上面的代码是错误的,他没同步两个线程,那么我们看看结果是什么样子的:

7035b99d43b084639847dcd3c275c715.png果然出现了线程不安全的情况。

那么,我们马上同步化我们的addStudent方法或者是run方法,代码如下:

这里同步addStudent方法

//添加学生,同步化该方法

public synchronized void addStudent(Student student){

System.out.println("添加前现在有"+class1.students.size()+"个学生");

class1.students.add(student);

System.out.println("添加后现在有"+class1.students.size()+"个学生");

}

结果如下:

4d1c60e7ae61383c584354b74deaa02a.png还是不同步的。

ef495f5bac11054e6e16912941de2928.png那么这到底是为什么呢?

三.解决方法

其实我们无论在ClassText类里面的哪个方法加synchronized使其同步化都是没有用的,因为你同步化的是你的ClassText对象,而我们要同步的是处理的是在ClassText类中组合Class对象,因为我们是对他的进行共享资源的操作,那么问题来了,怎么对不是本身对象进行一个同步化操作呢?还是使用synchronized同步代码块只不过同步对象不再是this了而是共享数据处理的对象,修改代码如下:

//添加学生

public void addStudent(Student student){

//同步化修改共享数据的对象

synchronized (class1){

System.out.println("添加前现在有"+class1.students.size()+"个学生");

class1.students.add(student);

System.out.println("添加后现在有"+class1.students.size()+"个学生");

}

}

结果如下:

c6662169c8dbbc14fb106ac5a0ae72e9.png没毛病了!

当然你把添加学生的添加函数放到Class类中,同步改方法也是没问题的

所以还是那一条,同步化的对象,是需要同步化的对象。

Java的synchronized的同步代码块和同步方法的区别

synchronized同步方法和同步代码块的区别 同步方法默认使用this或者当前类做为锁. 同步代码块可以选择以什么来加锁,比同步方法更精确,我们可以选择只有会在同步发生同步问题的代码加锁,而并不 ...

Java并发——synchronized关键字

前言: 只要涉及到Java并发那么我们就会考虑线程安全,实际上能够实现线程安全的方法很多,今天先介绍一下synchronized关键字,主要从使用,原理介绍 一.synchronized的使用方法 1 ...

精通java并发-synchronized关键字和锁

目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages synchronized关键字和锁 示例代码 public class MyThreadTest2 { public ...

Java并发-Synchronized关键字

一.多线程下的i++操作的并发问题 package passtra; public class SynchronizedDemo implements Runnable{ private static ...

java 并发——synchronized

java 并发--synchronized 介绍 在平常我们开发的过程中可能会遇到线程安全性的问题,为了保证线程之间操作数据的正确性,我们第一想到的可能就是使用 synchronized 并且 syn ...

0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

java提高篇&lpar;十二&rpar;-----代码块

在编程过程中我们可能会遇到如下这种形式的程序: public class Test { { } } 这种形式的程序段我们将其称之为代码块,所谓代码块就是用大括号({})将多行代码封装在一起, ...

随机推荐

sqlServer去除字段中的中文

很多时候数据库表中某些字段是由中文和字母或数字组成,但有时我们又需要将字段中的中文去掉.想要实现这种需求的方法有很多,下面就是其中一种解决方法. 首先我们先建立测试数据 create table te ...

hive 内部表和外部表的区别和理解

1. 内部表 create table test (name string , age string) location '/input/table_data'; 注:hive默认创建的是内部表 此时 ...

codeforces 484C Strange Sorting Codeforces Round &num;276 &lpar;Div&period; 1&rpar; C

思路:首先 他是对1到k 元素做一次变换,然后对2到k+1个元素做一次变化....依次做完. 如果我们对1到k个元素做完一次变换后,把整个数组循环左移一个.那么第二次还是对1 到 k个元素做和第一次一 ...

PIC32MZ tutorial -- Timer Interrupt

An interrupt is an internal or external event that requires quick attention from the controller. The ...

iOS图片加载新框架 - FlyImage

FlyImage 整合了SDWebImage,FastImageCache,AFNetworking的优点,是一个新的性能高效.接口简单的图片加载框架. 特点 高效 可将多张小图解码后存储到同一张大图 ...

xml 解析 java 基础复习

document  解析 sax  解析 dom4j 解析(摘自csdn redarmychen) dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个非常 ...

javascript 给关键字加链接

var keys = { "和尚":["http://www.baidu.com","#ff0000"], "系统":[ ...

futex-based pthread&lowbar;cond

pthread_cond的实现使用了几个futex来协同进行同步,以及如何来实现的. 假定你已经明白 futex,futex-requeue,以及 pthread lowlevellock. < ...

Centos6&period;5部署Rsyslog&plus;LogAnalyzer中文乱码解决

中文乱码 [root@log include]# pwd /zhang/app/loganalyzer-/src/include [root@log include]# vim functions_c ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值