不同的对象

public class Sync {
public synchronized void test() {
System.out.println("test start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test end");
}
}

#

public class MyThread extends Thread{
public void run() {
Sync sync = new Sync();
sync.test();
} public static void main(String[] args) {
for (int i = 0; i < 3; ++i) {
Thread thread = new MyThread();
thread.start();
}
}
}

执行结果

test start
test start
test start
test end
test end
test end  

现象

在MyThread中,每次都new一个新的Sync对象,可以看到代码块test虽然被加了synchonized但是还是并行执行的,初步结论:锁住的不是代码块

同一个对象

public class MyThread2 extends Thread{
public Sync sync;
MyThread2(Sync sync) {
this.sync = sync;
} public void run() {
System.out.println("hi....");
sync.test();
} public static void main(String[] args) {
Sync sync = new Sync();
for (int i = 0; i < 3; ++i) {
Thread thread = new MyThread2(sync);
thread.start();
}
}

执行结果

hi....
test start
hi....
hi....
test end
test start
test end
test start
test end  

现象

可以看到当他们共用一个对象的时候,synchonized起了作用,这块代码是串行执行的

结论

锁住的是对象

如何在多对象的时候任然锁住代码?

解决也很简单,只要锁住同一个对象就行了。例如:synchronized后的括号中锁同一个固定对象,这样就行了。

这样是没问题,但是,比较多的做法是让synchronized锁这个类对应的Class对象。

public class Sync2 {
public void test() {
synchronized (Sync2.class) {
System.out.println("test start");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test end");
}
}
}

#

public class MyThread3 extends Thread{
public void run() {
Sync2 sync = new Sync2();
sync.test();
} public static void main(String[] args) {
for (int i = 0; i < 3; ++i) {
Thread thread = new MyThread3();
thread.start();
}
}
}

执行结果

test start
test end
test start
test end
test start
test end

synchronized的两大不足

  • 由于我们没办法设置synchronized关键字在获取锁的时候等待时间,所以synchronized可能会导致线程为了加锁而无限期地处于阻塞状态
  • 使用synchronized关键字等同于使用了互斥锁,即其他线程都无法获得锁对象的访问权。这种策略对于读多写少的应用而言是很不利的,因为即使多个读者看似可以并发运行,但他们实际上还是串行的,并将最终导致并发性能的下降。

虽然synchronized已经作为一个关键字被固化在Java语言中了,但它只提供了一种相当保守的线程安全策略,且该策略开放给程序员的控制能力极弱

参考

synchonized控制对象还是代码段

synchronized的两大不足

synchronized锁住的是代码还是对象的更多相关文章

  1. Java线程同步:synchronized锁住的是代码还是对象

    所以我们在用synchronized关键字的时候,能缩小代码段的范围就尽量缩小,能在代码段上加同步就不要再整个方法上加同步.这叫减小锁的粒度,使代码更大程度的并发.原因是基于以上的思想,锁的代码段太长 ...

  2. synchronized锁住的是代码还是对象,以及synchronized底层实现原理

    synchronized (this)原理:涉及两条指令:monitorenter,monitorexit:再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令monitorenter和 ...

  3. Java并发,synchronized锁住的内容

    synchronized用在方法上锁住的是什么? 锁住的是当前对象的当前方法,会使得其他线程访问该对象的synchronized方法或者代码块阻塞,但并不会阻塞非synchronized方法. 脏读 ...

  4. Java多线程5:Synchronized锁机制

    一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...

  5. java内置锁实现锁住代码块方案(同一个对象或锁住整个类.class)

    我们看一个例子: class Demo { public synchronized void test() { System.out.println("test方法开始执行,当前线程为:&q ...

  6. 015-线程同步-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现

    一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. syn ...

  7. Java synchronized(this)锁住的是什么

    synchronized锁住的是括号里面的对象,而不是代码. 对于非static的synchronized方法,锁的就是对象本身,也就是this.

  8. java synchronized究竟锁住的是什么

    刚学java的时候,仅仅知道synchronized一个线程锁.能够锁住代码,可是它真的能像我想的那样,能够锁住代码吗? 在讨论之前先看一下项目中常见关于synchronized的使用方法: publ ...

  9. synchronized和ReentrantLock锁住了谁?

    一.synchronized 案例1: public class LockDemo{ public static void main(String[] args) throws Exception { ...

随机推荐

  1. 《笨方法学Python》加分题6

    types_of_people = 10 x = f"There are {types_of_people} types of peoples." binary = "b ...

  2. webplus知识点小结

    1.返回首页,要在首页栏目里面加链接,直接预览站点的时候地址栏那个地址就行 2.上传图片变色问题,要传jpg格式,不要png 3.留言板制作:后台组件管理->留言板->获取链接 然后在留言 ...

  3. Java第四次实验

    实验一: Android Stuidio的安装测试: 参考<Java和Android开发学习指南(第二版)(EPUBIT,Java for Android 2nd)>第二十四章: 参考ht ...

  4. NFS服务简介与配置

    NFS简介 NFS特点 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源 在NFS的应用中, ...

  5. eclipse启动时出现无法创建java虚拟机

    最 近一直在用eclipse开发android程序,今天不知怎么的启动eclipse时就会出现Failed to create java virtual machine,无法打开eclipse程序,折 ...

  6. codeforces 508B

    B. New Year Permutation time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. Java中资料的上传与下载

    1.导架包 <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons ...

  8. OpenCV与QT联合开发示例

    1.OpenCV及QT开发环境搭建 windows基于vs2017的opencv安装 windows下安装QT并与visual studio 2017搭建开发环境 2.工程创建 1.导入Qt项目 选择 ...

  9. POJ2516K次费用流建图

    Description: N个订单(每个订单订K种商品),M个供应商(每个供应商供应K种商品),K种商品,后N行,表示每一个订单的详细信息,后M行表示每个供应商供应的详细信息,后K 个N * M的矩阵 ...

  10. 冲刺博客NO.10

    今天做了什么:将程序整合到一起,出现了不少小错误,但是在讨论后都解决了. 遇到的难题:没遇到什么大困难