用生活例子来解释Java synchronized块
今天满世界的微信小程序的新闻,大家都说对于Android原生程序有构成危险了,我也不想了,以后的事谁知道呢, 我还是好好执行一下今年的计划吧。 项目刚刚上线,最近没啥事,我一直感觉自己的Java基础不够扎实,于是就想恶补下一下基础。记得大学英语老师告诉我们,学习要学会炒冷饭,多重复。 我就先从Java多线程的知识再拿出来巩固下,话说无论是从事J2EE还是Android开发,如果对多线程的知识掌握的不好,无论是面试还是工作都说不过去的,至少你不敢说熟悉Java.
我们都知道synchronized关键字可以让线程同步,但是如果用的位置不好,导致运行效率要降低很多。废话不多说,先上代码。
public class Worker { private Random random=new Random();
private ArrayList<Integer> list1=new ArrayList<>();
private ArrayList<Integer> list2=new ArrayList<>(); private synchronized void stageOne(){ try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list1.add(random.nextInt(100)); } private synchronized void stageTwo(){ try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list2.add(random.nextInt(100)); } private void process(){
for(int i=0;i<1000;i++){
stageOne();
stageTwo();
}
} public void test(){
long start=System.currentTimeMillis(); Thread t1=new Thread(new Runnable() { @Override
public void run() {
process();
}
});
t1.start(); Thread t2=new Thread(new Runnable() { @Override
public void run() {
process(); }
});
t2.start(); try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} long end = System.currentTimeMillis(); System.out.println("耗时:"+(end-start));
System.out.println("list1 size:"+list1.size()+" list2 size:"+list2.size());
}
}
耗时:5057
list1 size:2000 list2 size:2000
把代码改进后,代码如下:
package cave; import java.util.ArrayList;
import java.util.Random; public class Worker { private Random random=new Random();
private ArrayList<Integer> list1=new ArrayList<>();
private ArrayList<Integer> list2=new ArrayList<>(); private Object lock1=new Object();
private Object lokck2=new Object(); private void stageOne(){
synchronized (lock1) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list1.add(random.nextInt(100));
} } private void stageTwo(){
synchronized (lokck2) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list2.add(random.nextInt(100));
} } private void process(){
for(int i=0;i<1000;i++){
stageOne();
stageTwo();
}
} public void test(){
long start=System.currentTimeMillis(); Thread t1=new Thread(new Runnable() { @Override
public void run() {
process();
}
});
t1.start(); Thread t2=new Thread(new Runnable() { @Override
public void run() {
process(); }
});
t2.start(); try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} long end = System.currentTimeMillis(); System.out.println("耗时:"+(end-start));
System.out.println("list1 size:"+list1.size()+" list2 size:"+list2.size());
} }
耗时:2536
list1 size:2000 list2 size:2000
从耗时来看,改进后代码时间比之前少了近一半. 我这里stageOne和stageTwo方法代码比较简单,只有一个for循环。如果这个方法里代码有很多,其中一部分是耗时操作,你还把 synchronized关键字来修饰方法,那么耗时将会更多。所以涉及到的线程同步,synchronized所约束的范围越小越好,性能才会越高。这样说可能有点难以理解。我来打个比方吧,如果你去一个店里买衣服,看到一件衣服非常满意,就想去试一下衣服,这个时候正常情况下导购会告诉你试衣间在哪,让你过去试试衣服,你去了试衣间,然后把门关上,这个就相当于加synchronized关键字了。当然了,有的人进去不是去试衣服的,比如2015年的北京三里屯优衣库试衣间那一对男女是在玩耍,我们也管不了,对吧。不过,那个视频看得真是带劲,我还发给一个女生看了。试衣完毕,肯定出来了,其他人会进去锁上门,试衣服。这样进啊出啊进啊出啊,这个试衣间的锁就是相当于synchronized关键字。那么试想有一种情景:你去买衣服,当你要试衣服的时候,你告诉导购要把店面的大门关上(这个时候在外面大门加锁,相当于synchronized),其他人在外面等候,而且店面是上海南京东路步行街的一家店,人流量巨大。如果每个人试衣服都要求导购把店面大门关上,估计你下个月看不到这个店了,因为它关门倒闭了。你换个衣服这样折腾,这生意还能做下去吗?我估计是来了一个大明星,比如汤唯来到南京东路步行街买衣服,那大门估计真的要关上,不然多少男生要流口水啊,这个生意也没法做啊。总之,试衣服只要把试衣间的门锁上就好了,不用关上大门了。
好了,这么一说,你应该理解了为什么synchronized块比synchronized修饰方法性能高了吧,如果还想不通,就想一想你在店外面等着人家试衣服,如果一对男女进去试衣服,你想偷拍都不行啊,这多着急啊,我能理解你的心情!恩,记得只要在试衣间试衣服,坚决不出去。
用生活例子来解释Java synchronized块的更多相关文章
- Java同步块(synchronized block)使用详解
Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) 实例方法同步 静 ...
- Java多线程初学者指南(12):使用Synchronized块同步变量
我们可以通过synchronized块来同步特定的静态或非静态方法.要想实现这种需求必须为这些特性的方法定义一个类变量,然后将这些方法的代码用synchronized块括起来,并将这个类变量作为参数传 ...
- java synchronized修饰普通方法,修饰静态方法,修饰代码块,修饰线程run方法 比较
synchronized用于多线程设计,有了synchronized关键字,多线程程序的运行结果将变得可以控制.synchronized关键字用于保护共享数据. synchronized实现同步的机制 ...
- Java多线程初学者指南(11):使用Synchronized块同步方法
synchronized关键字有两种用法.第一种就是在<使用Synchronized关键字同步类方法>一文中所介绍的直接用在方法的定义中.另外一种就是synchronized块.我们不仅可 ...
- java synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
- Java synchronized
1. 将synchronized加在方法上, 即可实现对此方法的同步 public synchronized void deposit(float amt) { float tmp = amount; ...
- [zt]java synchronized详解
作者:GangWang 出处:http://www.cnblogs.com/GnagWang/ 记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多 ...
- java synchronized类锁,对象锁详解(转载)
觉得还不错 留个记录,转载自http://zhh9106.iteye.com/blog/2151791 在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看 ...
- Java同步块
原文:http://ifeve.com/synchronized-blocks/ Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本 ...
随机推荐
- Ajax请求过程中显示“进度”的简单实现
Ajax在Web应用中使用得越来越频繁.在进行Ajax调用过程中一般都具有这样的做法:显示一个GIF图片动画表明后台正在工作,同时阻止用户操作本页面(比如Ajax请求通过某个按钮触发,用户不能频繁点击 ...
- Dreamweaver 添加 cakephp ctp后缀名
Dreamweaver 默认是不支持ctp文件高亮的,即使用Dreamweaver打开ctp文件,也只能像记事本一样编辑 但是我们可以通过修改两个文件,来添加Dreamweaver对ctp文件的扩展支 ...
- centos 挂载与卸载硬盘
fdisk -l //先查询未挂载的硬盘名如:sdb1 等 mkfs.ext3 /dev/xvdb 开始格式化 df -h mount /dev/xvdb /home 开始挂载 vi /etc/fst ...
- Universal-Image-Loader(UIL)使用方法&流程图&源码分析 ----- 未完
GitHub源码: Android-Universal-Image-Loader Features Multithread image loading (async or sync) 多线程加载(同步 ...
- IOS 获得通讯录中联系人的所有属性 备用参考
ABAddressBookRef addressBook = ABAddressBookCreate(); CFArrayRef results = ABAddressBookCopyArrayOfA ...
- MongoDB 覆盖索引查询
MongoDB 覆盖索引查询 官方的MongoDB的文档中说明,覆盖查询是以下的查询: 所有的查询字段是索引的一部分 所有的查询返回字段在同一个索引中 由于所有出现在查询中的字段是索引的一部分, Mo ...
- 使用WampServer 3.0
在server上安装了WampServer 发现本地使用良好,但是无法从别的PC访问. 原因有二: 1.现象:输入连接无反应 原因:server本身用了80端口,所有WampServer我就设置了80 ...
- Burp Suite Walkthrough(中文版)
Burp Suite是Web应用程序测试的最佳工具之一,其多种功能可以帮我们执行各种任务.请求的拦截和修改,扫描web应用程序漏洞,以暴力破解登陆表单,执行会话令牌等多种的随机性检查.本文将做一个Bu ...
- 年度十佳 DevOps 博客文章(后篇)
如果说 15 年你还没有将 DevOps 真正应用起来,16 年再不实践也未免太落伍了.在上篇文章中我们了解到 15 年十佳 DevOps 博客文章的第 6-10 名,有没有哪一篇抓住了您的眼球,让您 ...
- POJ 3321 Apple Tree(树状数组)
点我看题目 题意 : 大概是说一颗树有n个分岔,然后给你n-1对关系,标明分岔u和分岔v是有边连着的,然后给你两个指令,让你在Q出现的时候按照要求输出. 思路 :典型的树状数组.但是因为没有弄好数组 ...