线程:synchronized
对象锁
关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当做锁。
锁重入
synchronized拥有锁重入功能,也就是在使用synchronized时, 当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁的。
可重入锁: 自己可以再次获取自己的内部锁。
public class Service {synchronized public void service1(){System.out.println("service1...");service2();}synchronized public void service2(){System.out.println("service2...");service3();}synchronized public void service3(){System.out.println("service3...");}
}
当存在父子类继承关系时,子类是完全可以通过"可重入锁"调用父类的同步方法的。
public class Main {public int i = 10;synchronized public void operateMainMethod(){try{i--;System.out.println("main print i="+i);Thread.sleep(1000);}catch(InterruptedException e){e.printStackTrace();}}
}public class Sub extends Main {synchronized public void operateISubMethod(){try{while(i>0){i--;System.out.println("sub print i="+i);Thread.sleep(100);this.operateMainMethod();}}catch(InterruptedException e){e.printStackTrace();}}
}
出现异常,锁自动释放
当一个线程执行的代码出现异常时,其所持有的锁会自动释放。
同步不具有继承性
同步是无法继承的
public class Main {synchronized public void serviceMethod(){try{System.out.println("int main 下一步 sleep begin threadName="+Thread.currentThread().getName() +" time="+System.currentTimeMillis());Thread.sleep(5000);System.out.println("int main 下一步 sleep end threadName="+Thread.currentThread().getName() +" time="+System.currentTimeMillis());}catch(InterruptedException e){e.printStackTrace();}}
}public class Sub extends Main{@Overridepublic void serviceMethod(){try{System.out.println("int sub 下一步 sleep begin threadName="+Thread.currentThread().getName() +" time="+System.currentTimeMillis());Thread.sleep(5000);System.out.println("int sub 下一步 sleep end threadName="+Thread.currentThread().getName() +" time="+System.currentTimeMillis());}catch(InterruptedException e){e.printStackTrace();}}
}
synchronized同步语句块
1. synchronized方法是对当前对象进行加锁, 而synchronized代码块是对某一个对象进行加锁。
2. synchronized代码块间也具有同步性, 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将被阻塞,这说明synchronized使用的"对象监视器"是一个。
3. synchronized(this)代码块是锁定当前对象的。
4. 多对象时候,锁住代码
只要锁住同一个对象就行了。例如: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(class)代码块
关键字synchronized还可以应用在static静态方法上,这是对当前的*.java文件对应的Class类进行持锁。
synchronized加到static静态方法上是给Class类上锁, 而synchronized关键字加到非static静态方法上是给对象上锁。
Class锁可以对类的所有对象实例起作用。
数据类型String的常量池特性
jvm中具有String常量池缓存的功能,因此大多数情况下,同步synchronized代码块都不使用String作为锁对象,而改用其他。
方法帧: 第一块:局部变量表 第二块:操作数栈 第三块:指向常量池的指针。
线程:synchronized相关推荐
- 线程 synchronized锁机制
脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过 ...
- 一、Java并发编程之线程、synchronized
黑马课程 文章目录 1. Java线程 1.1 创建和运行线程 方法一:Thread 方法二:Runnable(推荐) lambda精简 Thread和runnable原理 方法三:FutureTas ...
- Java中的ReentrantLock和synchronized两种锁定机制的对比
原文:http://www.ibm.com/developerworks/cn/java/j-jtp10264/index.html 多线程和并发性并不是什么新内容,但是 Java 语言设计中的创新之 ...
- Java并发 正确终止与恢复线程
为什么80%的码农都做不了架构师?>>> 前面提到了stop().suspend()等方法在终止与恢复线程的弊端,那么问题来了,应该如何正确终止与恢复线程呢?这里可以使用两种方 ...
- Synchronized关键字和锁升级
一.Synchronized 对于多线程不安全(当数据共享(临界资源),而多线程同时访问并改变该数据时,就会不安全),JAVA提供的锁有两个,一个是synchronized关键字,另外一个就是lock ...
- java synchronized wait
在多个线程要互斥访问数据, 但线程间需要同步时--例如任务分多个阶段,特定线程负责特定阶段的情况, 经常合作使用synchronized 和 wait() /*** * 计算输出其他线程锁计算的数据* ...
- java并发synchronized 锁的膨胀过程(锁的升级过程)深入剖析(2)
接下来我们分析两个批量偏向撤销的相关案例(禁止偏向锁延迟的情况下:-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0): 案例一: 1 2 3 ...
- java 停止线程播放音频_Notification 播放 关闭 声音----转载
NotificationPlayer.java 定义一个播放Notification声音的player,本质上仍然是一个MediaPlayer,这个是多线程编程的很好的例子 public class ...
- JAVA 多线程 JAVA 如何开发一个自定义线程池
1.多线程设计介绍 每一个线程的启动和结束都是比较消耗时间和占用资源的. 如果在系统中用到了很多的线程,大量的启动和结束动作会导致系统的性能变卡,响应变慢. 为了解决这个问题,引入线程池这种设计思想. ...
最新文章
- iOS-获取通讯录联系人信息
- JS模板引擎handlerbars入门
- Python进阶07 函数对象
- LTE Module User Documentation(翻译5)——Mobility Model with Buildings
- mysql Insert on duplicate引发的死锁
- WPF自定义控件与样式(1)-矢量字体图标(iconfont)
- char数组拷贝wchar数组
- https open api_通过bilibili_api获取弹幕+绘制词云的方法
- 后台性能测试不可不知的二三事
- c语言c程序由函数构成 每个函数完成相对独立的功能,17秋学期(1709)《C语言程序设计》在线作业 满分...
- Tornado请求分析request, 获取请求参数
- 数据挖掘与数据化运营实战. 3.9 卖家(买家)交易模型
- bp神经网络预测案例python_详细BP神经网络预测算法及实现过程实例
- W3school笔记——HTML
- 金仓数据库学习笔记(一)
- 计算机服务添加打印机服务,无法添加打印机报错后台程序服务没有运行的解决方法...
- 如何优雅的学习英语?从理解英语的使用思维开始!
- qq三国华容道算法(拼图问题,8数码问题?)
- Javascript高级程序设计——9.正则表达式(1)
- python请输入一个三位数输出该三位数的逆序数_编写程序,从键盘输入一个三位数,求出其逆序数并输出,例如输入123,输出321。...