用生活例子来解释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同步块用来避免竞争.本 ...
随机推荐
- post提交与get提交的一个小知识点
今天偶然发现post提交与get提交的一个小知识点,记下来以后可以看看. 将form表单的method的设置为get后,通过url传递的参数将不会被传递到服务器,例如1.ashx?a=123,的a=1 ...
- NetBeans中文乱码解决办法
一.Windows下NetBeans中文乱码解决办法 找到你的Netbeans安装目录下的etc文件夹,用记事本打开netbeans.conf,找到netbeans_default_options(不 ...
- ctrl+c关闭多线程python程序
项目中经常需要用到多线程,如果一个python程序用了多线程,当子线程没有结束时,用ctrl+c是关闭不了主线程的,这时候就只能用kill命令杀掉,这样会很麻烦. 所以探讨了下怎么ctrl+C关闭多线 ...
- 【转】oracle 针对中文字段进行排序
1)按笔画排序 select * from Table order by nlssort(columnName,'NLS_SORT=SCHINESE_STROKE_M') 2)按部首排序 select ...
- mysql将多张表COUNT的数据相加
由于数据量过大,我们将根据用户id 将数据存储在不同的表中,根据用户id模10的余数作为表的后缀.有如下十张表:test_0, test_1, ... ,test_9现在需要根据某个条件查询统计数据我 ...
- 软件测试 -- Bug等级划分规范
1. Blocker级别——中断缺陷 客户端程序无响应,无法执行下一步操作. 2. Critical级别――临界缺陷,包括: 功能点缺失,客户端爆页. 3. Major级别——较严重缺陷,包括: 功能 ...
- CODEVS 3286 火柴排队
[题目描述 Description] 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为: ,其中 ai表示 ...
- GO语言函数与类型
package main import () import ( "fmt" "reflect" "errors" ) type age in ...
- unity 基础之PhysicsManager
原地址:http://www.cnblogs.com/alongu3d/p/3644725.html @by 广州小龙 1.Gravity(重力) 物理系统都是根据实际情况进行模拟的,由于Y值是往下 ...
- SecureCRT自动登陆到服务器的脚本以及脚本编写简单说明
http://blog.csdn.net/marising/article/details/6409196 Secure用SSH登陆服务器时,如果服务器较多,登陆一次很麻烦,所以,可以自己编写VBSc ...