首页 > 试题广场 >

说说你了解的线程同步方式

[问答题]
说说你了解的线程同步方式
1、Java通过加锁实现线程同步,锁有两类:synchronized和Lock。 2、synchronized加在三个不同的位置,对应三种不同的使用方式,这三种方式的区别是锁对象不同: (1.)加在普通方法上,则锁是当前的实例(this)。 (2.)加在静态方法上,锁是当前类的Class对象。 (3.)加在代码块上,则需要在关键字后面的小括号里,显式指定一个对象作为锁对象。 3、Lock支持的功能包括:支持响应中断、支持超时机制、支持以非阻塞的方式获取锁、支持多个条件变量(阻塞队列)。
发表于 2022-05-06 11:02:46 回复(2)
AQS是多线程同步器,它是JUC包中多个组建的底层实现,比如说像Lock,CountDownLatch,Semaphore都用到了AQS,从本质上来说AQS提供了两种锁的机制,分别是排他锁和共享锁,所谓排他锁就是存在多个线程去竞争同一共享资源的时候,同一个时刻只允许一个线程去访问这样一个共享资源,也就是说多个线程中,只能有一个线程去获得这样的一个锁的资源,比如Lock中的ReentrantLock重入锁,他的实现就是用到了AQS中的一个排他锁的功能。共享锁也称为读锁,就是同一时刻允许多个线程同时获得这样一个锁的资源,比如CountDownLatch以及Semaphore,都用到了AQS中的共享锁的功能。那么AQS作为互斥锁来说呢,他的整个设计体系中,需要解决三个核心的问题。第一个互斥变量的设计,以及如何保证多线程更新互斥变量的时候线程的安全性,第二个未竞争到锁资源的线程的等待,以及竞争到锁的线程,释放锁之后的唤醒,第三个锁竞争的公平性和非公平性。AQS采用了一个int类型的互斥变量state用来记录锁竞争的一个状态,0表示当前没有任何线程竞争锁资源,而大于等于1表示已经有线程正在持有锁资源。一个线程来获取锁资源的时候,首先判断state是否等于0,也就是无锁状态,如果是则把这个state更新成1,而这个过程中,如果多个线程同时去做这样一个操作,就会导致线程安全性的问题,因此AQS采用了CAS机制,去保证state互斥变量更新的一个原子性。未获取锁的线程通过unsafe类中的park方法去进行阻塞,把阻塞的线程按照先进先出的原则去加入到一个双向链表的一个结构中,当获得锁资源的线程释放锁之后,会从这样一个双向链表的头部去唤醒下一个等待的线程,再去竞争锁。最后关于锁竞争的公平性和非公平性的问题AQS的处理方法是,在竞争锁资源的时候公平锁需要去判断双向链表中是否有阻塞的线程,如果有则需要去排队等待,而非公平锁的处理方式是不管双向链表中是否存在阻塞的线程,那么他都会直接去尝试更改互斥变量state去竞争锁,假设在一个临界点,获得锁的线程释放锁,此时state等于0,而当前的这个线程去抢占锁的时候正好可以把state修改成1,那么这个时候就表示他可以拿到锁,这个过程是非公平的。
发表于 2022-04-19 14:51:03 回复(2)
java通过加锁的方式实现线程同步,锁有两类,分别是synchronized和Lock。或是使用volatile修饰变量
发表于 2022-04-24 17:19:19 回复(0)
1、Java通过加锁实现线程同步,锁有两类:synchronized和Lock。 2、synchronized加在三个不同的位置,对应三种不同的使用方式,这三种方式的区别是锁对象不同: (1.)加在普通方法上,则锁是当前的实例(this)。 (2.)加在静态方法上,锁是当前类的Class对象。 (3.)加在代码块上,则需要在关键字后面的小括号里,显式指定一个对象作为锁对象。 3、Lock支持的功能包括:支持响应中断、支持超时机制、支持以非阻塞的方式获取锁、支持多个条件变量(阻塞队列)
发表于 2022-05-26 17:28:02 回复(0)
java主要通过加锁的方式实现线程同步:主要有两种方式:synchronized关键字和lock接口。synchronized可以加在三个不同的位置,对应着三种不同范围,区别是锁对象的不同:1.加在实例方法上,锁的就是当前的实例。2.加在静态方法和类上,锁的就是当前整个类。3.加在代码块上,锁的就是代码块里面的内容。我们应该合理的选择锁的对象。lock锁接口除了支持上述功能外,还支持了响应中断,超时机制,阻塞队列等。
发表于 2022-05-24 19:50:09 回复(0)
线程同步的方式有两类:lock和Synchorized. synchorized线程同步的时候加锁可以在普通方法上,静态方法上,和静态代码块。 不同点:lock支持响应中断,支持超时机制,支持以非阻塞的方式方式获取锁,支持多个变量。
发表于 2022-05-07 14:35:32 回复(0)
synchroized和lock嘛 Java主要通过加锁的方式实现的线程同步,synchroizd可以加锁的,加在this上,加在静态方法上,加在代码块上。不同的位置,锁的粒度不同。 Lcok接口实现上述功能。Lock是采用CAS+volatile实现的,核心是AQS线程同步器。
发表于 2022-09-13 18:14:29 回复(0)
在一般情况下,创建一个线程是不能提高程序的执行效率的,所以要创建多个线程。但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对同一个内存地址进行写入,由于CPU时间调度上的问题,写入数据会被多次的覆盖,所以就要使线程同步。 同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。 “同”字从字面上容易理解为一起动作 其实不是,“同”字应是指协同、协助、互相配合。 如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。例如Window API函数SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的LRESULT值返回给调用者。 在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。
发表于 2022-05-11 10:27:33 回复(0)
Java使用synchronized关键字或者Lock类或者volatile修饰变量。synchronized可修饰普通方法(加锁对象为当前对象)、静态方法(类)、静态代码块,Lock类支持超时机制、支持以非阻塞的方式获取锁、支持多个变量(阻塞队列)、支持响应中断。
发表于 2022-08-20 23:32:32 回复(0)
Java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间发生冲突,因此加入同步锁以避免在线程没有完成操作之前,被其他线程调用,从而保证了该变量的唯一性和准确性。Java主要是通过加锁的方式实现线程同步,而锁主要有两类,分别是:synchronized和lock。 同步方法:用synchronized关键字修饰的方法,由于Java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法,在调用该方法时,需要获得内置锁,否则就处于阻塞状态,synchronized关键字也可以修饰静态方法,此时如果调用该方法,则会锁住当前类的class对象。 同步代码块:有synchronized关键字修饰的语句块,被该关键字修饰的语句块会自动被加上内置锁,从而实现同步,但是同步是一种高开销的操作,因此应该减少同步的内容,通常没有必要同步整个方法,使用关键字同步关键代码块即可,根据要锁定的范围,准确的选择对象,从而准确的锁定锁的粒度,降低锁带来的性能开销。 使用重入锁实现线程同步:Synchronized设计之初没有考虑到超时机制,非阻塞形式以及多个条件变量。因此在JDK1.5引入了lock接口,并通过lock支持了上述的功能,包括:支持响应中断,支持超时机制,支持以非阻塞的方式获取锁,支持多个条件变量(阻塞队列)。在JavaSE5.0中新增了一个java.util.concurrent包来支持同步,reentrantLock类是可重入,互斥,实现了lock接口的锁,扩展了synchronized的能力。关于Lock对象和synchronized关键字的选择:最好两个都不用,使用一种java.util.concurrent包提供的机制,能够帮助用户处理所有与锁有关的代码,如果使用synchronized关键字能够满足用户的需求,就用synchronized,因为可以简化代码,如果需要更高级的功能,就用reentrantlock类,但是要注意及时释放锁,否则会出现死锁,通常在finally代码块释放锁。 Synchronized采用CAS+Mark Word实现,为了性能的考虑,并通过锁升级机制降低锁的开销。Synchronized会随着多线程的竞争的加剧,按照如下步骤逐步升级:无锁,偏向锁,轻量级锁,重量级锁。Lock则采用CAS+volatile实现,其实现核心是AQS,AQS是线程同步器,是一个线程同步的基础框架,它基于模板方法模式,在具体的Lock实例中,锁的实现是通过继承AQS来实现的,并且可以根据锁的使用场景,派生出公平锁,不公平锁,读锁,写锁等具体的实现。
发表于 2022-07-27 15:36:06 回复(0)
syn 与lock syn: 自动加锁与释放、不公平、内置锁。 lock: 手动加和释放,公平性、带条件变量,带超时获取、api
发表于 2024-05-28 15:29:59 回复(0)
Java中提供给我们使用的同步方案,从轻到重有三种方式:原子类、volatile关键字、锁。 1.原子类是juc atomic包下的一系列类,通过CAS(比较与交换机制)实现线程安全的更新共享变量 2.volatile关键字是轻量级的同步机制,它实现了变量的可见性、防止指令重排序 3.java中常用的两种锁,synchronized+juc包下的lock锁
发表于 2024-05-23 23:07:13 回复(0)
java通过加锁来实现线程同步,锁有两种,synchronized和lock synchronized可以加在三个不同位置上,1加在成员方法上,对当前实例对象加锁 2加在静态方法对,对当前类的class对象加锁 3对代码块加锁,指定对象加锁 lock支持的功能包括:支持响应中断,支持超时机制,支持以非阻塞的方法获取锁,支持多个条件变量(阻塞队列)
发表于 2024-05-15 19:57:36 回复(0)
线程同步方式synchronized 、lock synchronized可以加在三个不同的位置,对应三种不同的使用方式,区别是锁对象不同:1.加在普通方法上,则锁对象是当前实例this;2.加在静态方法上,则锁对象是当前类的Class对象。;3.加在代码块上,则需要在关键字后的小括号里,显示指定一个对象作为锁对象。采用”CAS+Mark Word“ lock支持:响应中断、超时机制、以非阻塞的方法获取锁,支持多个条件变量(阻塞队列)。采用”CAS+volatile“实现,实现的核心是AQS. AQS是线程同步器。
发表于 2024-04-26 21:30:41 回复(0)
synchronized和lock
发表于 2024-04-03 09:59:39 回复(0)
synchronized锁 是jvm层面的锁,是公平锁,lock锁基于aqs的方式来实现,以非阻塞的方式获取锁,支持非公平锁和公平锁。
编辑于 2024-04-02 15:37:54 回复(0)
synchroized和lock,Java主要通过加锁的方式实现的线程同步,synchroized是Java自带的锁,在jvm中会有一个锁的标记进行判断是否进行了加锁,以及有monitor监视器,它从无锁->偏向锁->轻量级锁(15)->重量级锁->自旋锁的一个转变,而lock的话是AQS同步器的一种实现,是通过cas+voiltaile关键字实现的,内部维护了一个state的属性,如果为1则说明锁已经被持有。或者使用juc包下的AtomicInteger、LongAdder原子类,或者是Sempater信号量,以及使用CountDown
发表于 2024-04-01 17:34:36 回复(0)
答: 线程同步是指在多线程环境下,控制多个线程对共享资源的访问顺序,以避免数据竞争和不一致性。 互斥锁,通过synchronized关键字和lock接口实现。synchronized可以加在三个不同的位置,对应三种不同的使用方式。加在普通方法上,则锁是当前实例。加在静态方法上,则锁是当前类的class对象。加在代码块上,则需要在关键字后面的小括号里,显式指定一个对象作为锁对象。
编辑于 2024-03-27 21:27:18 回复(0)
编辑于 2024-03-06 15:32:32 回复(0)
synchronized关键字: 1. 普通方法,锁的是this对象 2. 静态方法,锁的是class类对象 3. 代码块,锁的是对象 Lock锁 支持响应中断、支持超时机制、支持以非阻塞的方式获取锁、支持多个条件变量(阻塞队列)
发表于 2024-02-28 20:51:23 回复(0)