黑马------synchronized详解
黑马程序员:Java培训、Android培训、iOS培训、.Net培训
JAVA线程-synchronized详解
一、synchronized概述
1、线程间实现互斥,必须使用同一个监视器(一个对象)
2、synchronized的作用:为同步代码块或同步方法指定监视器
3、使用同一个监视器的多块代码块或多个方法,在任何时刻,只有获得监视器的线程可访问其中的一块代码块或方法。

二、synchronized作用对象
1、synchronized语句块:需要显式指定监视器
1)生成一个对象obj,synchronized(obj){代码块}
2)synchronized(this){代码块}
3)synchronized(className.class){代码块}
2、synchronized方法:使用默认的监视器
1)实例方法,默认的监视器为:this
2)类方法,默认的监视器为:className.class(Class对象)
三、看似使用了同一个监视器,实际不是
1、使用方法体内的对象作为监视器
public void method(){
Object obj = new Object();
synchronized(obj){代码块}
}
原因:每次调用该法,都会产生新的对象obj,即新的监视器,线程间不会使用同一个监视器
解决办法:使用类的实例成员,即把“Object obj = new Object();”放到方法体外
2、使用类实例成员作为监视器需要注意两个个问题:
(1)当这个成员指向的对象发生改变时,监视器就会发生改变。例如:
String str = new String(“123”);
public synchronized(str) void method1(){……} // method1使用监视器”123”
str = new String(“456”);
public synchronized(str) void method2(){……} // method2使用监视器”456”
原因:使用不同的监视器,method1与method2不能同步。如果通过方法改变str的指向,则会出现令人迷惑的同步问题。
解决办法:作为监视器的类实例成员使用final声明
(2)使用类实例成员作为类方法的监视器是错误的:即实例成员不能作为类方法的监视器。
3、实例方法和类方法
public synchronized void objMethod(){ ….. }
public static synchronized void staticMethod(){……}
原因:实例方法使用的监视器是:this;而类方法使用的监视器是:className.class
解决办法:将实例方法改为如下
public synchronized(className.class) void objMethod(){ ….. }
一个问题:子线程循环10次,然后主线程循环20次,如此循环30次
技术要点:1、轮询条件
2、使用Object的wait()和notify()
技术要求:1、子线程任务:循环10次
2、主线程任务:循环20次
3、子线程任务与主线程任务存在关联(轮流运行),应当放在同一个类(类的封装设计原则之一)
4、子线程任务与主线程任务需要协作
5、子线程任务和主线程任务各执行30次
可使用阻塞队列设计思想来修改Business的代码:注意判断条件
class Business{
private boolean isSubSchudule = ture; //使用boolean变量实现线程间协作
public synchronized void sub(int loop){
while (!isSubSchudule) { //这里可使用while替换if,避免假唤醒
try{
this.wait();
}catch(…){
…..
}
}
for(int i = 0; i < 10; i++){
System.out.println(“sub :” + i + “ loop:” + loop);
}
isSubSchudule = false;
this.notify();
}
public synchronized void main(int loop){
while (isSubSchudule){ //这里可使用while替换if,避免假唤醒
try{
this.wait();
}catch(…){
…..
}
}
for(int i = 0; i < 20; i++){
System.out.println(“main : :” + i + “ loop:” + loop);
}
isSubSchudule = ture;
this.notify();
}
}
//main()
Business business = new Business();
Thread thread = new Thread(new Runnable(){
public void run(){
for(int i = 0; i < 30; i++){business.sub(i);}}}).start();
for(int i = 0; i < 30; i++){ //将任务加入到主线程种,不用实现Runnable
business.main(i);
黑马------synchronized详解的更多相关文章
- Java synchronized 详解
Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ...
- 剑指Offer——线程同步volatile与synchronized详解
(转)Java面试--线程同步volatile与synchronized详解 0. 前言 面试时很可能遇到这样一个问题:使用volatile修饰int型变量i,多个线程同时进行i++操作,这样可以实现 ...
- synchronized详解
关于synchronized,本文从使用方法,底层原理和锁的升级优化这几个方面来介绍. 1.synchronized的使用: synchronized可以保证在同一时刻,只有一个线程可以操作共享变量, ...
- JAVA 中 synchronized 详解
看到一篇关于JAVA中synchronized的用法的详解,觉得不错遂转载之..... 原文地址: http://www.cnblogs.com/GnagWang/archive/2011/02/27 ...
- java并发编程(七)synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized( ...
- java synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
- Java中synchronized详解
synchronized 原则: 尽量避免无谓的同步控制,同步需要系统开销,可能造成死锁 尽量减少锁的粒度 同步方法 public synchronized void printVal(int v) ...
- [zt]java synchronized详解
作者:GangWang 出处:http://www.cnblogs.com/GnagWang/ 记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多 ...
- JAVA多线程synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同 ...
随机推荐
- c# DataGridView 的一些属性设置,序号,合并头
this.dataGridView1.DataSource = this.dISASTERBindingSource; this.dataGridView1.Locatio ...
- C#中MySQL数据库的备份 还原 初始化
直接在cmd执行如下代码: mysqldump -h localhost -uroot -p123 --default-character-set=utf8 --opt --disable-keys ...
- EasyUI表单内容整理
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 异步函数封装请确保异步性(Javascript需要养成的良好习惯)
背景假设: 你有许多的配置信息存放在服务器上,因为配置太多,不希望每次都把所有的配置信息都写到前端,希望能需要用的时候再获取就好了. 因为Javascript单线程运行,你不希望堵塞ui渲染于是你专门 ...
- 设置dos窗口的背景色与前景色
在dos中输入help会列出各种命令,其中有一个color命令可以用来设置当前窗口的前景色和背景色,输入help color会列出使用方法,内容如下: 设置默认的控制台前景和背景颜色. COLOR [ ...
- 编程key note
一些日常发现的code better的要点.不断更新. * #include <assert.h> 使用断言* 每个模块(文件)应该有一个唯一的一个前缀,模块导出的所有全局名字都应以此前缀 ...
- Informatica - Powercenter 英文版资料(转载)
Informatica - Powercenter 英文版资料 http://gerardnico.com/wiki/powercenter/powercenter
- 作业8 Alpha阶段项目总结
我们的扫雷游戏已经基本完成. 游戏共分3个难度 每个难度的格数和雷的格数也有不同 具体的游戏会在展示时候让大家看到 小组成员分数: 史劭聪 20分 马浩然 20分
- 重置了下系统好多关于mysql密码的文章都很渣拷分好的备用
方法1: 用SET PASSWORD命令 mysql -u root mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass ...
- 有关javascript的性能优化(合理的管理内存)
使用具备垃圾收集机制的语言编写程序,开发人员一般不必操心内存管理的问题.但是,Javascript在进行内存管理及收集时面临的问题是有点与众不同.其中最主要的一个问题是分配给Web浏览器的可用内存数量 ...