深入理解使用synchronized同步方法和同步代码块的区别
一.代码块和方法之间的区别
首先需要知道代码块和方法有什么区别:
构造器和方法块,构造器可以重载也就是说明在创建对象时可以按照不同的构造器来创建,那么构造器是属于对象,而代码块呢他是给所有的对象初始化的。底下看一个列子:
public class Constructor_Methodblock {
private int num;
private String str;
//构造器
public Constructor_Methodblock(int num,String str){
System.out.println("\n************构造器****************");
System.out.println("在进入构造器之前成员变量的值为num:"+this.num+"str: "+this.str);
this.str=str;
this.num=num;
System.out.println("赋值之后num为"+num+"str为"+str);
}
//方法块
{
System.out.println("\n************代码块****************");
System.out.println("在进入方法块之前成员变量的值为num:"+num+"str: "+str);
num=1;
str="li";
System.out.println("赋值之后num为"+num+"str为"+str);
} public static void main(String[] args) {
new Constructor_Methodblock(2,"fei");
}
}
结果为:
发现代码块比构造器早执行,而且代码块是所有的对象都要执行的。
现在我们对代码块和方法有了一定的了解,那么同步方法有什么缺点使得我们需要同步代码块呢?
二.同步方法的缺点
来想象一个这样的情况:一个方法其中有一部分是需要计算数据花费时间不是那么长但是还有一部分他不需要处理数据但是他需要花费大量的时间,那么如果我们直接将这个方法同步化会导致整体的代码性能下降,而我们仅仅将这个计算数据部分同步保证共享数据计算没有问题,那么代码性能是不是就上去了呢?
来看直接同步化方法:
public class SynFun extends Thread {
private int num=10;//共享数据
@Override
public void run(){
try {
this.fun();//调用同步方法
} catch (InterruptedException e) {
e.printStackTrace();
}
} public synchronized void fun() throws InterruptedException {
//使用睡眠来模拟一下复杂但是对数据处理没有关系的部分,睡眠三秒
Thread.sleep(3000);
System.out.println("修改前的num为"+num);
num--;
System.out.println("修改后的num为"+num);
System.out.println("*************");
} public static void main(String[] args) { SynFun synFun=new SynFun();
Thread t1=new Thread(synFun);
Thread t2=new Thread(synFun);
t1.start();
t2.start(); }
}
结果为:出现结果时,先等待了三秒出现了第一个结果,在等待了三秒又出现了第二个结果。
改进一下:
public void fun() throws InterruptedException {
//使用睡眠来模拟一下复杂但是对数据处理没有关系的部分,睡眠三秒
Thread.sleep(3000);
synchronized (this){
System.out.println("修改前的num为"+num);
num--;
System.out.println("修改后的num为"+num);
}
System.out.println("*************");
}
就是利用同步化代码块,将共享数据处理的部分同步起来,而其他的部分就让他去交叉运行吧。
结果是一样的,但是出现结果就是三秒以后直接出现两个答案,说明整体性能直接上去了。
******************************************************题外话***********************************************************
Java多线程专题已经已经发表了五篇博客了,不少前辈(其实我还是一个大二的学生)都给出了很好的讲解和指导,在这里真的非常感谢你们。
if(对我的博客感兴趣){
点赞+关注;
}else{
没有else
}
深入理解使用synchronized同步方法和同步代码块的区别的更多相关文章
- synchronized同步方法和同步代码块的区别
同步方法默认使用this或者当前类做为锁. 同步代码块可以选择以什么来加锁,比同步方法更精确,我们可以选择只有会在同步发生同步问题的代码加锁,而并不是整个方法. 同步方法使用synchronized修 ...
- 牛客网Java刷题知识点之同步方法和同步代码块的区别(用synchronized关键字修饰)
不多说,直接上干货! 扩展博客 牛客网Java刷题知识点之多线程同步的实现方法有哪些 为何要使用同步? java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查 ...
- java的同步方法和同步代码块,对象锁,类锁区别
/** * @author admin * @date 2018/1/12 9:48 * 作用在同一个实例对象上讨论 * synchronized同步方法的测试 * 两个线程,一个线程调用synchr ...
- 对象及变量的并发访问(同步方法、同步代码块、对class进行加锁、线程死锁)&内部类的基本用法
主要学习多线程的并发访问,也就是使得线程安全. 同步的单词为synchronized,异步的单词为asynchronized 同步主要就是通过锁的方式实现,一种就是隐式锁,另一种是显示锁Lock,本节 ...
- 同步方法、同步代码块、volidate变量的使用
当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线程改过了. ...
- synchronized修饰方法和代码块的区别
先看一段代码 Class A { public synchronized methodA() {//对当前对象加锁 } public methodB() { synchronized(this){}/ ...
- Java的synchronized的同步代码块和同步方法的区别
synchronized同步方法和同步代码块的区别 同步方法默认使用this或者当前类做为锁. 同步代码块可以选择以什么来加锁,比同步方法更精确,我们可以选择只有会在同步发生同步问题的代码加锁,而并不 ...
- 线程同步 synchronized 同步代码块 同步方法 同步锁
一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
随机推荐
- Python events
Events不同线程之间同步对象 参数说明: # 实例化event对象 event = threading.Event() # 等待检测标志位被设定,标志位设置后就不阻塞了 # 客户机线程可以等待设置 ...
- Win10在右键菜单添加在此处打开命令窗口项
转载:https://jingyan.baidu.com/article/2d5afd6930107a85a2e28e2d.html 第一步:新建一个文本文档,输入如下代码,然后另存为OpenCmdH ...
- Python实战:网络爬虫都能干什么?
整站下载器:siteSucker https://blog.csdn.net/l_215851356/article/details/54377582 http://python.jobbole.co ...
- P1325 雷达安装
传送门 思路: 采取贪心的思想. 把每个岛屿看作圆心,以雷达的范围 d 为半径,求出与 x 轴的左右两个交点,两交点所夹的区间就需要放置一个雷达,这样就把这道题转换为了区间取点问题.在枚举岛屿时,记录 ...
- POJ 1088 滑雪(模板题 DFS+记忆化)
Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...
- 特效 左右滑动轮播图jQuery思路
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 下载并配置jdk
①下载jdk安装到本机,这里是jdk8下载地址,请根据自己机子的环境进行下载 https://www.oracle.com/technetwork/java/javase/downloads/jdk8 ...
- ES6与ES5对比 模板字符串
var title = '你好' ES5 var tpl1 = '<div>' + '<span>' + title + '</span>' '</div&g ...
- 万年不变话题cookie,简单总结
cookie是面试中经常会问到的一个问题,但是就我的项目实践来看,我用到的次数极少.有时候用到也不是为了存储用户名密码,只是存储一些需要记住的状态.可能和我的经验尚浅,涉足的项目不算多有关.这里简单做 ...
- Windows Server 2012 R2域控制器部署
1. 概述 该文档描述了在Windows 2012R2 系统上搭建域控的方式. 2. 具体步骤 2.1 首先我们先配置好IP地址.计算名(默认的计算机名比较长,后期其它计算机加入域控的时候需要输入比较 ...