导航:首页 > 编程语言 > java同步锁和互斥锁

java同步锁和互斥锁

发布时间:2021-12-03 09:13:20

① POS线程同步互斥锁和读写锁的区别和各自适用场景

线程同步的方式包括:互斥锁、读写锁、条件变量、信号量和令牌。

java语言为例:
用synchronized关键字修饰同步方法。
同步有几种实现方法分别是synchronized,wait与notify
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
同步是多线程中的重要概念。同步的使用可以保证在多线程运行的环境中,程序不会产生设计之外的错误结果。同步的实现方式有两种,同步方法和同步块,这两种方式都要用到synchronized关键字。
给一个方法增加synchronized修饰符之后就可以使它成为同步方法,这个方法可以是静态方法和非静态方法,但是不能是抽象类的抽象方法,也不能是接口中的接口方法。下面代码是一个同步方法的示例:
public synchronized void aMethod() {
// do something
}
public static synchronized void anotherMethod() {
// do something
}

线程在执行同步方法时是具有排它性的。当任意一个线程进入到一个对象的任意一个同步方法时,这个对象的所有同步方法都被锁定了,在此期间,其他任何线程都不能访问这个对象的任意一个同步方法,直到这个线程执行完它所调用的同步方法并从中退出,从而导致它释放了该对象的同步锁之后。在一个对象被某个线程锁定之后,其他线程是可以访问这个对象的所有非同步方法的。
同步块是通过锁定一个指定的对象,来对同步块中包含的代码进行同步;而同步方法是对这个方法块里的代码进行同步,而这种情况下锁定的对象就是同步方法所属的主体对象自身。如果这个方法是静态同步方法呢?那么线程锁定的就不是这个类的对象了,也不是这个类自身,而是这个类对应的java.lang.Class类型的对象。同步方法和同步块之间的相互制约只限于同一个对象之间,所以静态同步方法只受它所属类的其它静态同步方法的制约,而跟这个类的实例(对象)没有关系。

② 线程同步互斥锁和读写锁的区别和各自适用场景

线程同步的方式包括:互斥锁、读写锁、条件变量、信号量和令牌。互斥锁和读写锁:提供对临界资源的保护,当多线程试图访问临界资源时,都必须通过获取锁的方式来访问临界资源。(临界资源:是被多线程共享的资源)当读写线程获取锁的频率差别不大时,一般采用互斥锁,如果读线程访问临界资源的频率大于写线程,这个时候采用读写锁较为合适,读写锁允许多个读线程同时访问临界资源,读写线程必须互斥访问临界资源。读写锁的实现采用了互斥锁,所以在读写次数差不多的情况下采用读写锁性能没有直接采用互斥锁来的高。

③ java中实现同步的两种方式syschronized和lock的区别和联系

Lock是java.util.concurrent.locks包下的接口,Lock实现提供了比使用方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我们拿Java线程(二)中的一个例子简单的实现一下和sychronized一样的效果,代码如下:

[java]view plain

  • Thread-4准备读取数据

  • Thread-3准备读取数据

  • Thread-5准备读取数据

  • Thread-5读取18

  • Thread-4读取18

  • Thread-3读取18

  • Thread-2准备写入数据

  • Thread-2写入6

  • Thread-2准备写入数据

  • Thread-2写入10

  • Thread-1准备写入数据

  • Thread-1写入22

  • Thread-5准备读取数据

  • 从结果可以看出实现了我们的需求,这只是锁的基本用法,锁的机制还需要继续深入学习。

    本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7461369,转载请注明。

    在java中有两种方式实现原子性操作(即同步操作):
    1)使用同步关键字synchronized
    2)使用lock锁机制其中也包括相应的读写锁


    package com.xiaohao.test;

    import java.util.Random;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;

    public class Test {
    public static void main(String[] args) {
    final LockTest lock=new LockTest();
    //输出张三
    new Thread(){
    public void run(){
    lock.test("张三张三张三张三张三张三张三张三张三张三");
    }
    }.start();

    //输出李四
    new Thread(){
    public void run(){
    lock.test("李四李四李四李四李四李四李四李四李四李四");System.out.println
    (" ---------------------------------------------------------------");
    }
    }.start();


    //---------------------------------------------------------------
    //模拟写入数据的
    for (int i = 0; i < 3; i++) {
    new Thread(){
    public void run() {
    for (int j = 0; j < 5; j++) {
    // lock.set(new Random().nextInt(30));
    lock.set2(new Random().nextInt(30));

    }
    }
    }.start();

    }
    //模拟读取数据的
    for (int i = 0; i < 3; i++) {
    new Thread(){
    public void run() {
    for (int j = 0; j < 5; j++) {
    // lock.get();
    lock.get2();
    }
    }
    }.start();
    }


    }
    }

    class LockTest{
    private Lock lock=new ReentrantLock(); //创建普通的锁
    private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();//创建读写锁
    private int data;// 共享数据


    //实现同步的方法一 使用同步关键字 synchronized
    public synchronized void test(String name){
    //下面的相关操作是一个原子性的操作
    // lock.lock();// 得到锁
    try {
    for(int i = 0; i < name.length(); i++) {
    System.out.print(name.charAt(i));
    }
    } finally {
    // lock.unlock();// 释放锁
    }
    }
    //实现同步的方法二 使用lock锁机制
    public void test2(String name){
    //下面的相关操作是一个原子性的操作
    lock.lock();// 得到锁
    try {
    for(int i = 0; i < name.length(); i++) {
    System.out.print(name.charAt(i));
    }
    } finally {
    lock.unlock();// 释放锁
    }
    }


    //使用set方法模拟写入数据
    //使用 synchronized 实现了读读,写写,读写之间的互斥 ,但读读之间的互斥是没有什么必要的
    public synchronized void set(int data){
    System.out.println(Thread.currentThread().getName() + "准备写入数据");
    try {
    Thread.sleep(20);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    this.data = data;
    System.out.println(Thread.currentThread().getName() + "写入" + this.data);
    }

    //使用get方法模拟读取数据
    //使用 synchronized 实现了读读,写写,读写之间的互斥 ,但读读之间的互斥是没有什么必要的
    public synchronized void get() {
    System.out.println(Thread.currentThread().getName() + "准备读取数据");
    try {
    Thread.sleep(20);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "读取" + this.data);
    }


    //使用set方法模拟写入数据
    //使用 读写锁实现了写写,读写之间的互斥 ,但读读之间的互斥是没有什么必要的
    public void set2(int data){
    readWriteLock.writeLock().lock();//获取写入锁
    try{
    System.out.println(Thread.currentThread().getName() + "准备写入数据");
    try {
    Thread.sleep(20);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    this.data = data;
    System.out.println(Thread.currentThread().getName() + "写入" + this.data);
    }
    finally{
    readWriteLock.writeLock().unlock();
    }
    }


    //使用get方法模拟读取数据
    //使用 读写锁实现了写写,读写之间的互斥 ,但读读之间的互斥是没有什么必要的
    public void get2() {
    //获取相应的读锁
    readWriteLock.readLock().lock();
    try{
    System.out.println(Thread.currentThread().getName() + "准备读取数据");
    try {
    Thread.sleep(20);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "读取" + this.data);
    }
    finally{
    // 释放相应的写锁
    readWriteLock.readLock().unlock();
    }
    }

    }

    线程同步经典版:

    package com.xiaohao.test;

    import java.util.concurrent.locks.ReentrantReadWriteLock;

    public class Test2{

    public static void main(String[] args){

    final LockTest2 lockTest=new LockTest2();

    for(int i=0;i<3;i++) {

    new Thread(){

    public void run(){

    try {

    for (int j = 0; j < 3; j++) {

    lockTest.setValue();

    } } catch (InterruptedException e) {

    // TODO Auto-generated catch block e.printStackTrace();

    }

    }

    }.start();

    }

    for(int i=0;i<3;i++) {

    new Thread(){

    public void run(){

    try {

    for (int j = 0; j < 3; j++) {

    lockTest.getValue();

    }

    } catch (InterruptedException e)

    { // TODO Auto-generated catch block e.printStackTrace(); }

    }

    }.start();

    }

    }

    }

    class LockTest2 {

    int data=0;

    ReentrantReadWriteLock lock= new ReentrantReadWriteLock();// 锁对象

    public void setValue() throws InterruptedException{

    lock.writeLock().lock();

    System.out.println("正在使用写锁......");

    data=(int) (Math.random()*10);

    System.out.println("正在写入:"+data);

    Thread.sleep(500);

    System.out.println("写锁调用完毕---------------------------");

    lock.writeLock().unlock(); }

    public void getValue() throws InterruptedException{

    lock.readLock().lock();

    System.out.println("正在使用读锁...........................................");

    System.out.println("正在读入:"+data); Thread.sleep(500);

    System.out.println("读锁调用完毕......");

    lock.readLock().unlock();

    }

    }

    **** 当一个线程进入了一个对象是的synchronized方法,那么其它线程还能掉否调用此对象的其它方法?

    这个问题需要分几种情况进行讨论。

    1)查看其它方法是否使用了同步关键字(synchronized)修饰,如果没有的话就可以调用相关的方法。

    2)在当前synchronized方法中是否调用了wait方法,如果调用了,则对应的锁已经释放,可以访问了。

    3)如果其它方法也使用synchronized修饰,并且当前同步方法中没有调用wait方法的话,这样是不允许访问的。

    4)如果其它方法是静态方法的话,由于静态方法和对象是扯不上什么关系,对于静态同步方法而言,其对应的同步监视器为当前类的字节码

    所以肯定可以访问的了。

    ④ JAVA中线程在什么时候需要同步和互斥

    同步:上一段代码没的完成,下一段必须等到上一段代码完成后才可以执行。如买票排队
    异步:上一段代码没的完成,下一段不必等到上一段代码完成就可以执行。如手机发送短信。
    例如访问同一个资源:
    例如车站的售票系统,一定是多个线程同时运行售票的吧。
    有编号为10000这张票,那么线程thread1正在卖它的时候,其余的线程就不能也卖这张票了。
    另一个就是著名的生产者-消费者问题。类比一下,老爸挣钱,打到银行卡里,儿子花钱。(假设卡里有钱的话就暂时不打钱)
    对于老爸老说,如果要打钱,查看一下卡,如果有钱,就暂时不放,并通知儿子已经有钱;如果没钱,当然就打钱了。
    对于儿子来说,取钱时如果有钱就取,如果没有就等待,并通知老爸没钱了。
    这就是同步了
    如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。

    当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
    面试的话 你就这样告诉他
    线程的同步意味安全 譬如你取钱 你的执行语和我用的是相同对象 那你要在卡上扣除的钱数扣在我卡上了 怎么办

    至于异步 是JAVA的闪亮点 设想下你搜索时 并没有提交 只打上关键字 就出现了很多提示 ,另外 异步在 体育节目方面的应用 在网上 你可以宣称 你的产品 可以让顾客看到赛场的比赛时钟 这就是用异步实现的
    简单的说,同步就是防止多个线程访问同一个对象,造成数据不安全。
    比如:一个男生和一个女生是男女朋友的关系,那么,另外的一个男生要想追到这个女生,就得先等前面这个男生和这个女生分手了以后才可以,两个男生不能同时访问这个女生,这就是同步;异步就是,在一个家庭中,几个兄弟姐妹可以同时拥有相同的父母,不需要等待,都可以同时拥有,同时访问。

    ⑤ 如何在Java多线程编程中实现程序同与互斥

    作为一个完全面向对象的语言,Java提供了类 Java.lang.Thread 来方便多线程编程,这个类提供了大量的方法来方便我们控制自己的各个线程,我们以后的讨论都将围绕这个类进行。

    Thread 类最重要的方法是 run() ,它为Thread 类的方法 start() 所调用,提供我们的线程所要执行的代码。为了指定我们自己的代码,只需要覆盖它!

    方法一:继承 Thread 类,覆盖方法 run()

    我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可。

    下面是一个例子:

    public class MyThread extends Thread {

    int count= 1, number;

    public MyThread(int num) {

    number = num;

    System.out.println("创建线程 " + number);

    }

    public void run() {

    while(true) {

    System.out.println("线程 " + number + ":计数 " + count);

    if(++count== 6) return;

    }

    }

    public static void main(String args[]) {

    for(int i = 0; i < 5; i++) new MyThread(i+1).start();

    }

    }

    这种方法简单明了,符合大家的习惯,但是,它也有一个很大的缺点,那就是如果我们的类已经从一个类继承(如小程序必须继承自 Applet 类),则无法再继承 Thread 类,这时如果我们又不想建立一个新的类.

    一种新的方法:不创建 Thread 类的子类,而是直接使用它,那么我们只能将我们的方法作为参数传递给 Thread 类的实例,有点类似回调函数。但是 Java 没有指针,我们只能传递一个包含这个方法的类的实例。那么如何限制这个类必须包含这一方法呢?当然是使用接口!(虽然抽象类也可满足,但是需要继承,而我们之所以要采用这种新方法,不就是为了避免继承带来的限制吗?)

    Java 提供了接口 Java.lang.Runnable 来支持这种方法。

    方法二:实现 Runnable 接口

    Runnable 接口只有一个方法 run(),我们声明自己的类实现 Runnable 接口并提供这一方法,将我们的线程代码写入其中,就完成了这一部分的任务。

    但是 Runnable 接口并没有任何对线程的支持,我们还必须创建 Thread 类的实例,这一点通过 Thread 类的构造函数

    public Thread(Runnable target);

    来实现。

    下面是一个例子:

    public class MyThread implements Runnable {

    int count= 1, number;

    public MyThread(int num) {

    number = num;

    System.out.println("创建线程 " + number);

    }

    public void run() {

    while(true) {

    System.out.println("线程 " + number + ":计数 " + count);

    if(++count== 6) return;

    }

    }

    public static void main(String args[])

    {

    for(int i = 0; i < 5; i++) new Thread(new MyThread(i+1)).start();

    }

    }

    ⑥ java线程中的同步锁和互斥锁有什么区别

    ⑦ 自旋锁和互斥锁的区别 java中lock Syntronized区别

    自旋锁(Spin lock)
    自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是

    否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。其作用是为了解决某项资源的互斥使用。因为自旋锁不会引起调用者睡眠,所以自旋锁的效率远
    高于互斥锁。虽然它的效率比互斥锁高,但是它也有些不足之处:
    1、自旋锁一直占用CPU,他在未获得锁的情况下,一直运行--自旋,所以占用着CPU,如果不能在很短的时 间内获得锁,这无疑会使CPU效率降低。
    2、在用自旋锁时有可能造成死锁,当递归调用时有可能造成死锁,调用有些其他函数也可能造成死锁,如 _to_user()、_from_user()、kmalloc()等。

    因此我们要慎重使用自旋锁,自旋锁只有在内核可抢占式或SMP的情况下才真正需要,在单CPU且不可抢占式的内核下,自旋锁的操作为空操作。自旋锁适用于锁使用者保持锁时间比较短的情况下。

    两种锁的加锁原理

    互斥锁:线程会从sleep(加锁)——>running(解锁),过程中有上下文的切换,cpu的抢占,信号的发送等开销。

    自旋锁:线程一直是running(加锁——>解锁),死循环检测锁的标志位,机制不复杂。

    互斥锁属于sleep-waiting类型的锁。例如在一个双核的机器上有两个线程(线程A和线程B),它们分别运行在Core0和
    Core1上。假设线程A想要通过pthread_mutex_lock操作去得到一个临界区的锁,而此时这个锁正被线程B所持有,那么线程A就会被阻塞
    (blocking),Core0 会在此时进行上下文切换(Context
    Switch)将线程A置于等待队列中,此时Core0就可以运行其他的任务(例如另一个线程C)而不必进行忙等待。而自旋锁则不然,它属于busy-waiting类型的锁,如果线程A是使用pthread_spin_lock操作去请求锁,那么线程A就会一直在
    Core0上进行忙等待并不停的进行锁请求,直到得到这个锁为止。

    两种锁的区别

    互斥锁的起始原始开销要高于自旋锁,但是基本是一劳永逸,临界区持锁时间的大小并不会对互斥锁的开销造成影响,而自旋锁是死循环检测,加锁全程消耗cpu,起始开销虽然低于互斥锁,但是随着持锁时间,加锁的开销是线性增长。

    两种锁的应用

    互斥锁用于临界区持锁时间比较长的操作,比如下面这些情况都可以考虑

    1 临界区有IO操作

    2 临界区代码复杂或者循环量大

    3 临界区竞争非常激烈

    4 单核处理器

    至于自旋锁就主要用在临界区持锁时间非常短且CPU资源不紧张的情况下,自旋锁一般用于多核的服务器。

    lock与Syntronized的区别

    转自自:

    java并发之Lock与synchronized的区别

    1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;

    2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;

    3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;

    4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

    5)Lock可以提高多个线程进行读操作的效率。

    在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。

    两者在锁的相关概念上区别:

    1.可重入锁

    如果锁具备可重入性,则称作为可重入锁。像synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。

    看下面这段代码就明白了:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    class MyClass
    {

    public synchronized void method1()
    {

    method2();

    }

    public synchronized void method2()
    {

    }

    }

    上述代码中的两个方法method1和method2都用synchronized修饰了,假如某一时刻,线程A执行到了method1,此时线程A获取了这个对象的锁,而由于method2也是synchronized方法,假如synchronized不具备可重入性,此时线程A需要重新申请锁。但是这就会造成一个问题,因为线程A已经持有了该对象的锁,而又在申请获取该对象的锁,这样就会线程A一直等待永远不会获取到的锁。

    而由于synchronized和Lock都具备可重入性,所以不会发生上述现象。

    2.可中断锁

    可中断锁:顾名思义,就是可以相应中断的锁。

    在Java中,synchronized就不是可中断锁,而Lock是可中断锁。

    如果某一线程A正在执行锁中的代码,另一线程B正在等待获取该锁,可能由于等待时间过长,线程B不想等待了,想先处理其他事情,我们可以让它中断自己或者在别的线程中中断它,这种就是可中断锁。

    在前面演示lockInterruptibly()的用法时已经体现了Lock的可中断性。

    3.公平锁

    公平锁即尽量以请求锁的顺序来获取锁。比如同是有多个线程在等待一个锁,当这个锁被释放时,等待时间最久的线程(最先请求的线程)会获得该所,这种就是公平锁。

    非公平锁即无法保证锁的获取是按照请求锁的顺序进行的。这样就可能导致某个或者一些线程永远获取不到锁。

    在Java中,synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。

    而对于ReentrantLock和ReentrantReadWriteLock,它默认情况下是非公平锁,但是可以设置为公平锁。

    看一下这2个类的源代码就清楚了:

    在ReentrantLock中定义了2个静态内部类,一个是NotFairSync,一个是FairSync,分别用来实现非公平锁和公平锁。

    我们可以在创建ReentrantLock对象时,通过以下方式来设置锁的公平性:

    1

    ReentrantLock
    lock = new ReentrantLock(true);

    如果参数为true表示为公平锁,为fasle为非公平锁。默认情况下,如果使用无参构造器,则是非公平锁。

    另外在ReentrantLock类中定义了很多方法,比如:

    isFair() //判断锁是否是公平锁

    isLocked() //判断锁是否被任何线程获取了

    isHeldByCurrentThread() //判断锁是否被当前线程获取了

    hasQueuedThreads() //判断是否有线程在等待该锁

    在ReentrantReadWriteLock中也有类似的方法,同样也可以设置为公平锁和非公平锁。不过要记住,ReentrantReadWriteLock并未实现Lock接口,它实现的是ReadWriteLock接口。

    4.读写锁

    读写锁将对一个资源(比如文件)的访问分成了2个锁,一个读锁和一个写锁。

    正因为有了读写锁,才使得多个线程之间的读操作不会发生冲突。

    ReadWriteLock就是读写锁,它是一个接口,ReentrantReadWriteLock实现了这个接口。

    可以通过readLock()获取读锁,通过writeLock()获取写锁。

    性能比较

    在JDK1.5中,synchronized是性能低效的。因为这是一个重量级操作,它对性能最大的影响是阻塞的是实现,挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给系统的并发性带来了很大的压力。相比之下使用Java提供的Lock对象,性能更高一些。Brian

    Goetz对这两种锁在JDK1.5、单核处理器及双Xeon处理器环境下做了一组吞吐量对比的实验,发现多线程环境下,synchronized的吞吐量下降的非常严重,而ReentrankLock则能基本保持在同一个比较稳定的水平上。但与其说ReetrantLock性能好,倒不如说synchronized还有非常大的优化余地,于是到了JDK1.6,发生了变化,对synchronize加入了很多优化措施,有自适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在JDK1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地,所以还是提倡在synchronized能实现需求的情况下,优先考虑使用synchronized来进行同步。

    ⑧ 多线程的同步和互斥有什么区别

    举例说明:
    假如把整条道路看成是一个【进程】的话,那么马路中间白色虚线分隔开来的各个车道就是进程中的各个【线程】了。
    ①这些线程(车道)共享了进程(道路)的公共资源(土地资源)。
    ②这些线程(车道)必须依赖于进程(道路),也就是说,线程不能脱离于进程而存在(就像离开了道路,车道也就没有意义了)。
    ③这些线程(车道)之间可以并发执行(各个车道你走你的,我走我的),也可以互相同步(某些车道在交通灯亮时禁止继续前行或转弯,必须等待其它车道的车辆通行完毕)。
    ④这些线程(车道)之间依靠代码逻辑(交通灯)来控制运行,一旦代码逻辑控制有误(死锁,多个线程同时竞争唯一资源),那么线程将陷入混乱,无序之中。
    ⑤这些线程(车道)之间谁先运行是未知的,只有在线程刚好被分配到CPU时间片(交通灯变化)的那一刻才能知道。
    注:
    由于用于互斥的信号量sem与所有的并发进程有关,所以称之为公有信号量。公有信号量的值反映了公有资源的数量。只要把临界区置于P(sem)和V(sem)之间,即可实现进程间的互斥。就象火车中的每节车厢只有一个卫生间,该车厢的所有旅客共享这个公有资源:卫生间,所以旅客间必须互斥进入卫生间,只要把卫生间放在P(sem)和V(sem)之间,就可以到达互斥的效果。

    ⑨ synchronized实现何时使用了自旋锁还是互斥锁

    synchronized的锁是针对多线程的,从线程的角度去思考才能真正弄明白。

    Java的synchronized使用方法总结
    1. 把synchronized当作函数修饰符时
    这也就是同步方法,那这时synchronized锁定的是哪个对象呢?它锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却可以任意调用这个被加了synchronized关键字的方法。
    同步块,示例代码如下:
    public void method3(SomeObject so)
    {
    synchronized(so)
    {
    //…..
    }
    }
    这时,锁就是so这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁。
    3.将synchronized作用于static 函数,示例代码如下:
    Class Foo
    {
    public synchronized static void methodAAA() // 同步的static 函数
    {
    //….
    }
    public void methodBBB()
    {
    synchronized(Foo.class) // class literal(类名称字面常量)
    }
    }
    代码中的methodBBB()方法是把class literal作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。

    阅读全文

    与java同步锁和互斥锁相关的资料

    热点内容
    哪吒最新出的电影 浏览:823
    一个泰国小孩走丢的电影 浏览:514
    《重回寻秦记之风流少龙》 浏览:801
    免费影院网页 浏览:316
    一部韩国片男主下面很大 浏览:595
    人理电影 浏览:92
    十部必看古董电影 浏览:895
    深田咏美电影推荐 浏览:351
    吸血鬼香港电影有哪些 浏览:876
    有个讲男人哺乳孩子的电影叫啥名字? 浏览:824
    电影古装鬼片在线观看 浏览:775
    汁圆影视 浏览:514
    主角老二被蛇咬的小说 浏览:498
    电影院评价在哪里看 浏览:85
    kk3影院 浏览:817
    小电影从哪里看 浏览:514
    下载电影的好网址11153 浏览:107
    花都之乱txt下载 浏览:891
    韩国孕妇生孩子电视剧大肚子 浏览:389
    主角把自己母亲收入后宫 浏览:25

    友情链接