摘要:线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他非同步方法对于静态同步方法,锁是针对这个类的,锁对象是该类的对象。
对实现了Runnable或者Callable接口类,可以通过多线程执行同一实例的run或call方法,那么对于同一实例中的局部变量(非方法变量)就会有多个线程进行更改或读取,这就会导致数据不一致,synchronized(关键字)可以解决多线程共享数据同步的问题synchronized使用说明 作用范围
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
修饰一个代码块:被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象
修饰一个非静态方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象
修改一个静态的方法:其作用的范围是整个静态方法,作用的对象是这个类的所有对象
修改一个类:其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象
高能提示:1. 修饰一个代码块
No1 > synchronized修饰的非静态方法:如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,则这个线程所属对象的其它线程不能同时访问这个对象中任何一个synchronized方法
No2 > synchronized关键字是不能继承的:基类的方法synchronized function(){}在继承类中并不自动是synchronized function(){},而是变成了function(){}。继承类需要你显式的指定它的某个方法为synchronized方法,可以通过子类调用父类的同步方法来实现同步
No3 > 针对synchronized修饰代码块和非静态方法,本质上锁的是代码块或非静态方法对应的对象(代码块是synchronized标注的变量,非静态方法是所在类对应的实例),如果是不同的对象是可以同时访问的
No4 > 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制
No5 > 每个对象只有一个锁(lock)与之相关联
No6 > 在定义接口方法时不能使用synchronized关键字
No7 > 构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步
public void syncCode(Object o) { synchronized (o) {// 同步代码块} }
上面的锁就是o这个对象,当然多个线程同步需要保证o这个对象是同一个,这是有明确的对象作为锁的情况,如果只是想单纯的让某一段代码同步,并没有明确的对象作为锁,可以创建一个特殊的instance变量来充当锁
synchronized(o)修饰的代码块,其中o可以取值一个对象或者一个变量或者this亦或者Clz.class
public class Sync implements Runnable { private byte[] lock = new byte[0]; public void syncCode() { synchronized (lock) {// 同步代码块} } public void run .... }
注:零长度的byte数组对象创建起来将比任何对象都经济,查看编译后的字节码,生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码2. 修饰一个非静态方法
public synchronized void method() {// .....}
此时锁的是调用这个同步方法的对象3. 修饰一个静态方法
public synchronized static void method() {// .....}
synchronized修饰的静态方法锁定的是这个类的所有对象4. 修饰类
public class Sync implements Runnable { public void syncCode() { synchronized (Sync.class) {// 同步代码块} } public void run .... }
和作用于静态方法一样,synchronized作用于一个类时,是给这个类加锁,类的所有对象用的是同一把锁总结
线程同步的目的是为了保护多个线程反问一个资源时对资源的破坏。
线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他非同步方法
对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,当在一个同步方法中访问另外对象上的同步方法时,会获取这两个对象锁。
对于同步,要时刻清醒在哪个对象上同步,这是关键。
编写线程安全的类,需要时刻注意对多个线程竞争访问资源的逻辑和安全做出正确的判断,对"原子"操作做出分析,并保证原子操作期间别的线程无法访问竞争资源。
当多个线程等待一个对象锁时,没有获取到锁的线程将发生阻塞。
死锁是线程间相互等待锁锁造成的,在实际中发生的概率非常的小,一旦程序发生死锁,程序将死掉
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/69513.html
摘要:线程线程是进程中的一个实体,作为系统调度和分派的基本单位。下的线程看作轻量级进程。因此,使用的目的是让相同优先级的线程之间能适当的轮转执行。需要注意的是,是线程自己从内部抛出的,并不是方法抛出的。 本文及后续相关文章梳理一下关于多线程和同步锁的知识,平时只是应用层面的了解,由于最近面试总是问一些原理性的知识,虽说比较反感这种理论派,但是为了生计也必须掌握一番。(PS:并不是说掌握原理不...
摘要:死亡线程方法执行结束,或者因异常退出了方法,则该线程结束生命周期。死亡的线程不可再次复生。直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。枚举程序中的线程。强迫一个线程等待。通知一个线程继续运行。 一. 线程状态转换图 showImg(https://segmentfault.com/img/bV38ef?w=968&h=680); 线程间的状态转换说明: 新建(new)...
摘要:线程启动规则对象的方法先行发生于此线程的每一个动作。所以局部变量是不被多个线程所共享的,也就不会出现并发问题。通过获取到数据,放入当前线程处理完之后将当前线程中的信息移除。主线程必须在启动其他线程后立即调用方法。 一、线程安全性 定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式,或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行...
摘要:当一个线程持有重量级锁时,另外一个线程就会被直接踢到同步队列中等待。 java代码先编译成字节码,字节码最后编译成cpu指令,因此Java的多线程实现最终依赖于jvm和cpu的实现 synchronized和volatile 我们先来讨论一下volatile关键字的作用以及实现机制,每个线程看到的用volatile修饰的变量的值都是最新的,更深入的解释就涉及到Java的内存模型了,我们...
阅读 1199·2021-11-24 11:16
阅读 3427·2021-11-15 11:38
阅读 1919·2021-10-20 13:47
阅读 546·2021-09-29 09:35
阅读 2191·2021-09-22 15:17
阅读 1012·2021-09-07 09:59
阅读 3373·2019-08-30 13:21
阅读 2903·2019-08-30 12:47