Java多线程之synchronized(三)
在多线程访问同一个对象中的不同的synchronized方法或synchronized代码块的前提下,也就是“对象监控器”为同一个对象的时候,也就是synchronized的锁为同一把锁的时候,调用的效果就是:当前正在执行的synchronized方法或synchronized代码块的运行结果是同步的,但是对其synchronized方法或synchronized代码块来说是阻塞的。同步是因为当一个线程执行synchronized方法或代码块的时候,正常情况下,别的线程永远得不到CPU的执行机会。也就是因为别的线程永远得不到执行机会,所以其他synchronized方法和synchronized代码块没有机会被执行,造成阻塞。
其实Java还支持“任意对象”作为“对象监视器”,来实现同步的功能,这个“任意对象”大多数为实例变量或者方法形参,使用的格式为synchronized(非this对象)同步代码块。那么她的特点和synchronized(this)代码块是一样的,特点如下:在多个线程持有“对象监视器”为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)代码块里的代码。我写了一个小例子来证明,代码如下:
public static void main(String[] args) {
MyService1 service = new MyService1();
ThreadA a = new ThreadA(service);
a.setName("A");
ThreadB b = new ThreadB(service);
b.setName("B");
a.start();
b.start();
}
public static class ThreadA extends Thread {
private MyService1 service;
public ThreadA(MyService1 service) {
super();
this.service = service;
}
@Override
public void run() {
super.run();
service.serviceMethodA("a", "A");
}
}
public static class ThreadB extends Thread {
private MyService1 service;
public ThreadB(MyService1 service) {
super();
this.service = service;
}
@Override
public void run() {
super.run();
service.serviceMethodA("b", "B");
}
}
}
class MyService1 {
private String userName, userPassWord;
String s = new String();
public void serviceMethodA(String userName, String userPassWord) {
synchronized (s) {
try {
System.out.println("线程" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "进入同步块");
Thread.sleep(5000);
System.out.println("线程" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "离开同步块");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果如下:从代码上可以看到,线程A和线程B访问的都是service这个对象,所以“对象监控器”为同一个对象,理论上,在这种情况,执行的结果应该是同步的,从控制台打印的结果来看,也确实是同步的。

那么synchronized(非this对象)有什么优点呢,我们假设在一个类中有很多synchronized修饰的方法,虽然可以实现同步,但是同时也形成了阻塞,这样就影响了运行效率,但是使用同步代码块非this锁就可以解决这个问题,因为非this锁和this锁是异步的,他们之间不会互相争夺锁,这样运行效率就提高了。下面看一个例子来证明这件事情,只需要在MyService1类里添加一个方法即可,然后线程B调用该方法。代码如下:
public void serviceMethodB(String userName, String userPassWord) {
synchronized (this) {
try {
System.out.println("线程" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "进入同步块");
Thread.sleep(5000);
System.out.println("线程" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "离开同步块");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果如下:由于“对象监视器”不同,所以运行的结果是异步的,这个异步说的是方法serviceMethodA和方法serviceMethodB之间是异步的,交叉执行的。

上面说过了多个线程同时访问synchronized(非this对象)代码块时,呈同步效果,也就是说必须一个线程执行完释放掉锁,另一个线程才可以执行。也说过了多个线程分别访问this锁和非this锁,呈异步效果,可以提高运行效率。接下来说一说多线程访问不同的对象是什么效果,也就是使用不同的“对象监视器”。下面看一个例子,代码如下:
public static void main(String[] args) {
MyService4 service = new MyService4();
MyObject1 object = new MyObject1();
MyObject1 object1 = new MyObject1();
//两个线程传入不同的对象
ThreadA a = new ThreadA(service, object);
a.setName("A");
ThreadB b = new ThreadB(service, object1);
b.setName("B");
a.start();
b.start();
}
public static class ThreadA extends Thread {
private MyService4 service;
private MyObject1 object;
public ThreadA(MyService4 service, MyObject1 object) {
super();
this.service = service;
this.object = object;
}
@Override
public void run() {
super.run();
service.serviceMethod(object);
}
}
public static class ThreadB extends Thread {
private MyService4 service;
private MyObject1 object;
public ThreadB(MyService4 service, MyObject1 object) {
super();
this.service = service;
this.object = object;
}
@Override
public void run() {
super.run();
service.serviceMethod(object);
}
}
}
class MyService4 {
public void serviceMethod(MyObject1 object) {
synchronized (object) {
try {
System.out.println("线程" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "进入同步块");
Thread.sleep(5000);
System.out.println("线程" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "离开同步块");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyObject1 {
}
运行结果如下:由结果可以看出来,如果使用不同的“对象监视器”,结果是异步执行的。

Java多线程之synchronized(三)的更多相关文章
- JAVA多线程之Synchronized关键字--对象锁的特点
一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...
- JAVA多线程之Synchronized、wait、notify实例讲解
一.Synchronized synchronized中文解释是同步,那么什么是同步呢,解释就是程序中用于控制不同线程间操作发生相对顺序的机制,通俗来讲就是2点,第一要有多线程,第二当多个线程同时竞争 ...
- (二)java多线程之synchronized
本人邮箱: kco1989@qq.com 欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kco github: https://github.com/kco198 ...
- Java多线程之synchronized及其优化
Synchronized和同步阻塞synchronized是jvm提供的同步和锁机制,与之对应的是jdk层面的J.U.C提供的基于AbstractQueuedSynchronizer的并发组件.syn ...
- java 多线程之synchronized wait/notify解决买票问题
一.Java线程具有五中基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread(); 就绪状态(Runnable):当调用线程对象的st ...
- Java多线程之synchronized详解
目录 synchronized简介 同步的原理 对象头与锁的实现 锁的优化与升级 Monitor Record 锁的对比 synchronized简介 synchronized关键字,一般称之为&qu ...
- Java多线程之synchronized(四)
前面几章都是在说synchronized用于对象锁,无论是修饰方法也好修饰代码块也好,然而关键字synchronized还可以应用到static静态方法上,如果这样写,那就是对当前的*.java文件所 ...
- JAVA多线程之synchronized和volatile实例讲解
在多线程中,提到线程安全.线程同步,我们经常会想到两个关键字:volatile和synchronized,那么这两者有什么区别呢? 1. volatile修饰的变量具有可见性 volatile是变量修 ...
- Java多线程之synchronized和volatile
概述 用Java来开发多线程程序变得越来越常见,虽然Java提供了并发包来简化多线程程序的编写,但是我们有必要深入研究一下,才能更好的掌握这块知识. 本文主要对Java提供的底层原语synchroni ...
随机推荐
- 使用mybatis查询数据,按特定顺序排序
有如下表table_people id name 1 dwyane 2 james 3 paul 4 bosh ...
- Android安装应用失败UID 和 PID
参考:http://blog.sina.com.cn/s/blog_62ef2f140101j6q2.html 安装任意第三方的一个apk,恢复出厂设置,再次安装相同的apk,提示安装失败,通过打印L ...
- ubuntu-10.04的测试环境 安装测试 Coreseek开源中文检索引擎-Sphinx中文版
主要参考文档:http://www.coreseek.cn/products-install/install_on_bsd_linux/ 一. 32位版本: coreseek安装需要预装的软件: ap ...
- latex 批量注释
在LaTex中的注释有3种方法: 1. 右键单击选中要注释的文本,选择 Insert Comment ,WinEdt 就会自动给选定的行添加 % ,完成段落文本的注释: 右键单击选中已经注释的文本,选 ...
- 配置Raspbian 启用SPI I2C
sudo vi /etc/modprobe.d/raspi-blacklist.conf 找到这两行 blacklist spi-bcm2708 blacklist i2c-bcm2708 注释掉 # ...
- KEIL的ARM编译器对RW和ZI段的一个处理
按照C编译器编译的结果,一般会产生RO段,RW段,ZI段.RO是程序中的指令和常量,RW是程序中的已初始化全局变量,ZI是程序中的未初始化或初始化为零的全局变量. 那么如下的代码 int aaa; i ...
- 转: Promises与Javascript异步编程
在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这些年浏览器技术.HTML5以及CSS3等的发展,越来越多的富Web应用出现:在给与我们良好体验的同时,Web开发人员在背后需要处理越来越多 ...
- ElasticSearch D3
http://www.elasticsearch.org/blog/data-visualization-elasticsearch-aggregations/
- Windows 系统消息范围和前缀,以及消息大全
Windows系统定义的消息类别消息标识符前缀 消息分类ABM 应用桌面工具栏消息BM 按钮控件消息CB 组合框控件消息CBEM 扩展组合框控件消息CDM 通用对话框消息DBT 设备消息DL 拖曳列表 ...
- Mysql 忘密码 + Phpadmin 修改密码无法登陆
mysql有时候忘记密码了怎么办?我给出案例和说明!一下就解决了! Windows下的实际操作如下 1.关闭正在运行的MySQL. 2.打开DOS窗口,转到mysql\bin目录. 3.输入mysql ...