synchronized同步方法的问题

有些情况下,在方法上面加synchronized同步,会有性能问题。
请看下面代码,来计算下两个线程执行的耗时:

package com.sutaoyu.Thread;

public class SynchronizedTest02 {
public static long begin1;
public static long end1;
public static long begin2;
public static long end2; public static void main(String[] args) {
final LongTask longTask = new LongTask(); Thread t1 = new Thread() {
public void run() {
begin1 = System.currentTimeMillis();
//执行耗时较长的任务方法
longTask.changeNum(true);
end1 = System.currentTimeMillis();
}
}; Thread t2 = new Thread() {
public void run() {
begin2 = System.currentTimeMillis();
//执行耗时较长的任务方法
longTask.changeNum(false);
end2 = System.currentTimeMillis();
}
}; t1.start();
t2.start(); //先让主线程睡眠,保证t1和t2线程执行完毕之后再计算时间
try {
Thread.sleep(10000);
}catch(InterruptedException e) {
e.printStackTrace();
} long begin = 0;
long end = 0; //将先执行的线程的时间和最后执行线程的时间获取到
if(begin1 > begin2) {
begin = begin2;
}else {
begin = begin1;
} if(end1 > end2) {
end = end1;
}else {
begin = begin1;
} if(end1 > end2) {
end = end1;
}else {
end = end2;
} System.out.println("两个线程总共耗时:" + (end -begin)/1000 + "秒"); }
}

使用同步代码块完善上面代码

上面代码打印结果是6秒,里面使用Thread.sleep方法来模拟了一个执行耗时较长的代码,假设这段代码并不会涉及到安全问题,所以就没有比较加入同步了。
来使用synchronized代码块来修改下上面的LongTask类。

package com.sutaoyu.Thread;

public class SynchronizedTest02 {
public static long begin1;
public static long end1;
public static long begin2;
public static long end2; public static void main(String[] args) {
final LongTask longTask = new LongTask(); Thread t1 = new Thread() {
public void run() {
begin1 = System.currentTimeMillis();
//执行耗时较长的任务方法
longTask.changeNum(true);
end1 = System.currentTimeMillis();
}
}; Thread t2 = new Thread() {
public void run() {
begin2 = System.currentTimeMillis();
//执行耗时较长的任务方法
longTask.changeNum(false);
end2 = System.currentTimeMillis();
}
}; t1.start();
t2.start(); //先让主线程睡眠,保证t1和t2线程执行完毕之后再计算时间
try {
Thread.sleep(10000);
}catch(InterruptedException e) {
e.printStackTrace();
} long begin = 0;
long end = 0; //将先执行的线程的时间和最后执行线程的时间获取到
if(begin1 > begin2) {
begin = begin2;
}else {
begin = begin1;
} if(end1 > end2) {
end = end1;
}else {
begin = begin1;
} if(end1 > end2) {
end = end1;
}else {
end = end2;
} System.out.println("两个线程总共耗时:" + (end -begin)/1000 + "秒"); }
}

修改后将需要同步的代码放到synchronized代码块中,再次运行SynchronizedTest02类,打印结果是3秒,因为那段耗时较长的代码是在异步情况下运行,所以节省了一些时间。

注意:多个线程在执行synchronized同步代码块时,代码块括号里面可以传入任意对象,但一定要保证多个线程访问的是同一个对象。

比如将LongTask中的成员变量Object obj = new Object();移动到changeNum方法中,在t1和t2两个线程中分别调用了changeNum方法,这样会各自创建一个Object对象,仍然会导致线程安全问题发生。

59、synchronized同步代码块的更多相关文章

  1. 线程同步 synchronized 同步代码块 同步方法 同步锁

    一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...

  2. synchronized(){}同步代码块笔记(新手笔记,欢迎纠正)

    /* 内容:同步代码块,目的是解决多线程中的安全问题.什么安全问题呢??就是在执行run方法时,假如线程-0刚刚获得执行权, *还没执行时,就挂那了,这时线程-1获得执行权,并进行执行,就有可能出现负 ...

  3. java中的synchronized同步代码块和同步方法的区别

    下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...

  4. 线程执行synchronized同步代码块时再次重入该锁过程中抛异常,是否会释放锁

    一个线程执行synchronized同步代码时,再次重入该锁过程中,如果抛出异常,会释放锁吗? 如果锁的计数器为1,抛出异常,会直接释放锁: 那如果锁的计数器为2,抛出异常,会直接释放锁吗? 来简单测 ...

  5. synchronized同步代码块锁释放

    今天发现自己写的线上程序出现数据库不能同步的问题,查看日志已经停止记录,随后使用jstack查看线程的运行状况,发现有个同步线程锁住了. 以下是jstack -l 637  问题线程的内容. &quo ...

  6. synchronized 同步代码块,售票问题

    package cn.ljs.FristSync; public class SalerDemo extends Thread { static int tickets = 1000; String ...

  7. java中多线程模拟(多生产,多消费,Lock实现同步锁,替代synchronized同步代码块)

    import java.util.concurrent.locks.*; class DuckMsg{ int size;//烤鸭的大小 String id;//烤鸭的厂家和标号 DuckMsg(){ ...

  8. Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...

  9. 对象及变量的并发访问(同步方法、同步代码块、对class进行加锁、线程死锁)&内部类的基本用法

    主要学习多线程的并发访问,也就是使得线程安全. 同步的单词为synchronized,异步的单词为asynchronized 同步主要就是通过锁的方式实现,一种就是隐式锁,另一种是显示锁Lock,本节 ...

随机推荐

  1. [转帖]Linux 下 DD 命令的使用详解

    https://blog.csdn.net/noviblue/article/details/56012275 一.dd命令的解释 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注 ...

  2. C++中sizeof操作符与strlen函数

    sizeof操作符: sizeof是一个操作符,返回一条表达式或一个类型名字所占的字节数.返回值一个常量表达式,类型为size_t. size_t sizeof(type) size_t sizeof ...

  3. Django知识总汇

    基础 Django基础 Django基本命令 model系统 ORM基础 ORM字段和参数 ORM对数据库操作 ORM中介模型 ORM之其他骚操作 templates系统 模板语言 views系统 视 ...

  4. 快速用梯度下降法实现一个Logistic Regression 分类器

    前阵子听说一个面试题:你实现一个logistic Regression需要多少分钟?搞数据挖掘的人都会觉得实现这个简单的分类器分分钟就搞定了吧? 因为我做数据挖掘的时候,从来都是顺手用用工具的,尤其是 ...

  5. 一文总结之MyBatis

    目录 MyBatis 目标 MyBatis演示 Configuration.xml 映射文件 初始化配置文件 Dao Spring与MyBatis集成 pom Spring配置文件 MyBatis配置 ...

  6. java 表单验证

    java 表单验证 1.思路:通过表单选择器,表单属性过滤器提取每个表单提交的值,进行验证 2.实现:javascript通过 onSubmit()事件,判断,返回值false不提交,返回true提交 ...

  7. CF1088F Ehab and a weird weight formula 贪心 倍增

    CF1088F Ehab and a weird weight formula 题意 给定一棵树,点有点权,其中这棵树满足除了权值最小的点外,每个点至少有一个点权小于它的相邻点. 要求你重新构建这棵树 ...

  8. BZOJ4727 [POI2017]Turysta 【竞赛图哈密顿路径/回路】

    题目链接 BZOJ4727 题解 前置芝士 1.竞赛图存在哈密顿路径 2.竞赛图存在哈密顿回路,当且仅当它是强联通的 所以我们将图缩点后,拓扑排序后一定是一条链,且之前的块内的点和之后块内的点的边一定 ...

  9. 【uoj131】 NOI2015—品酒大会

    http://uoj.ac/problem/131 (题目链接) 题意 给出一个字符串,每个后缀有一个权值${a_i}$,这些后缀两两之间存在公共前缀.问能够组成长度从0~n-1的公共前缀的后缀的方案 ...

  10. POJ.1986 Distance Queries ( LCA 倍增 )

    POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...