`
jokermanager
  • 浏览: 143724 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

关于用信号量Semaphore完成互斥锁Mutex

阅读更多
本文探讨用信号量Semaphore实现互斥锁Mutex的问题

    在Doug lea的那本著名的《Java并发编程—设计原则与模式》,英文名"<!---->Concurrent Programming in Java™: Design Principles and Patterns, Second Edition ",书中提到可以用信号量Semaphore实现互斥锁Mutex。虽然java中是通过synchronize关键字提供锁,并用这个基础设施实现信号量的。在有的系统中只有信号量这一原语,锁是通过信号量实现的。代码如下:

import java.util.concurrent.Semaphore;

public class Mutex ...{
     private Semaphore s = new Semaphore(1);

     public void acquire() throws InterruptedException ...{
      s.acquire();
     }
    public void release()...{
      s.release();
     }
    public boolean attempt(int ms) throws InterruptedException ...{
      return s.tryAcquire(ms);
     }
}


上面的代码只能在java5中编译通过,因为Semaphore是在java5中才提供的。我在读上面的代码时有疑问。因为如果错误的连续调用 release两次,然后两个线程都调用acquire,岂不是这两个线程都可以同时运行,从而违背了互斥锁的定义?为了证明我的猜测,写了如下的代码:

public class TestMutex ...{
    public static void main(String[] args) throws InterruptedException...{
        Mutex mutex=new Mutex();
        mutex.acquire();
        mutex.release();
        mutex.release();
        new MyThread(mutex).start();
        new MyThread(mutex).start();
    }

}

class MyThread extends Thread...{
    private Mutex mutex;

    public MyThread(Mutex mutex) ...{
        this.mutex=mutex;
    }

    public void run()...{
        try ...{
            mutex.acquire();
        } catch (InterruptedException e1) ...{
            throw new RuntimeException(e1);
        }
        for(int i=0;i<10;i++)...{
            System.out.print(i);
            if(i%3==0)...{
                try ...{
                    Thread.sleep(100);
                } catch (InterruptedException e) ...{
                    e.printStackTrace();
                }
            }
        }
        mutex.release();
    }
}

 该程序的输出如下:
00123123456456789789
从而证实了我的猜测。

作为对比,下面是采用synchronized关键字的互斥锁方案:

public class TestLock ...{
    public static void main(String[] args) throws InterruptedException...{
        new MyThread2().start();
        new MyThread2().start();
    }

}

class MyThread2 extends Thread...{
    public void run()...{
        synchronized(TestLock.class)...{
            for(int i=0;i<10;i++)...{
                System.out.print(i);
                if(i%3==0)...{
                    try ...{
                        Thread.sleep(100);
                    } catch (InterruptedException e) ...{
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

该程序的输出如下:
01234567890123456789
可见两个线程确实互斥运行。

这个问题产生的原因是虽 然在Mutex的定义中"private Semaphore s = new Semaphore(1)",也就是该信号量的初始permits是1, 但是在此后每次调用release方法都会导致permits加一。如果能限制permits最大值1,最小值0,那就是真正的Mutex了。

分享到:
评论
1 楼 Aoogoo 2010-07-29  
不错的文章,

相关推荐

    信号量与互斥锁示例代码

    首先,让我们详细探讨一下信号量(Semaphore)和互斥锁(Mutex)的概念。 1. **信号量**:信号量是一种计数器,用于管理共享资源的访问。它可以是整数值,表示资源的数量,或者作为二进制信号量(值只能为0或1),...

    mutex和semaphore互斥程序实例

    `mutex`(互斥锁)和`semaphore`(信号量)都是用于实现线程同步和互斥的工具,确保同一时间只有一个线程可以访问特定的共享资源。本文将深入探讨这两种机制及其在实际编程中的应用。 一、互斥锁(Mutex) 互斥锁是...

    C语言并发控制:信号量与互斥锁的实现与应用

    信号量(Semaphore)和互斥锁(Mutex)作为两种重要的同步机制,在确保数据一致性和防止竞争条件方面发挥着关键作用。 #### 二、信号量和互斥锁的概念 ##### 2.1 信号量 信号量是一种计数器,主要用于控制多个...

    互斥锁、条件变量、信号量总结

    互斥锁、条件变量和信号量是操作系统中用于线程同步和资源管理的重要工具,尤其在多线程和多进程编程中发挥着关键作用。这些机制确保了共享资源的有序访问,防止数据竞争和死锁等问题的发生。 首先,互斥锁(Mutex...

    互斥锁示例代码

    除了互斥锁,Linux还提供了信号量(Semaphore)、条件变量(Condition Variable)等同步机制,可以根据不同的应用场景选择合适的方法。 总之,互斥锁是保证多线程并发环境下数据安全的重要工具,通过理解其原理和...

    多线程 教程 各种锁 半成品的CAS 临界区 信号量 事件 互斥锁 队列

    本教程将深入探讨多线程相关的知识点,包括各种锁机制、条件变量、半成品的CAS操作、临界区、信号量、事件、互斥锁以及队列。 **多线程**:多线程是操作系统提供的一种并发执行机制,一个进程可以包含多个线程,每...

    Linux互斥锁、条件变量和信号量[归类].pdf

    Linux 互斥锁、条件变量和信号量 在 Linux 多线程编程中,为了防止多个线程同时访问共享资源,Linux 提供了互斥锁、条件变量和信号量来保护共享资源。 一、互斥锁 互斥锁是一种信号量,常用来防止两个进程或线程...

    信号量同步等待机制 semaphore wait-and-signal

    我们不仅需要使用互斥锁来保护队列的访问,还需要使用信号量来确保队列不会溢出或空闲。 ```plaintext // 初始化信号量 int empty = N; int full = 0; // 生产者函数 void producer() { while (true) { ...

    基于consul的分布式锁工具,包含:互斥锁、信号量等工具

    常见的分布式锁类型有互斥锁(Mutex)和信号量(Semaphore)。 - **互斥锁**:互斥锁确保同一时间只有一个线程可以访问资源,其他试图获取锁的线程必须等待锁被释放。在Java中,通常通过`java.util.concurrent....

    使用信号量和关键段实现多线程的同步与互斥

    信号量分为两种类型:互斥量(Mutex Semaphore)和计数信号量(Counting Semaphore)。互斥量仅允许一个线程访问资源,而计数信号量可以允许多个线程同时访问。 2. **互斥量(Mutex)** 互斥量用于实现互斥,即同一...

    跨平台的C++线程模板类和信号量及互斥量模板类

    在C++编程中,跨平台性是一个重要的考量因素,特别是在涉及到操作系统底层机制如线程、锁和信号量等时。本文将深入探讨标题和描述中提及的“跨平台的C++线程模板类”以及“信号量及互斥量模板类”。 首先,线程是...

    《临界区,互斥,信号量》

    为此,程序员们利用了一系列的技术来管理这种访问,其中包括临界区(CriticalSection)、互斥量(Mutex)以及信号量(Semaphore)。下面将详细介绍这些概念及其在实际开发中的应用。 #### 一、临界区(Critical ...

    Python的互斥锁与信号量详解

    在多线程编程中,互斥锁(Mutex)和信号量(Semaphore)是用来保证线程安全、控制对共享资源的并发访问的重要机制。Python通过threading模块提供了一套丰富的同步原语,包括互斥锁和信号量,使得开发者可以更加方便...

    LINUX内核信号量设计与实现.rar

    在Linux内核中,信号量分为两种类型:互斥信号量(mutex)和普通信号量(semaphore)。互斥信号量主要用于实现线程之间的互斥访问,而普通信号量则允许有限数量的进程同时访问资源。 1. **互斥信号量(Mutex)**: ...

    Python多线程操作之互斥锁、递归锁、信号量、事件实例详解

    为了解决这一问题,Python提供了多种同步机制,包括互斥锁、递归锁、信号量和事件。下面将详细介绍这些同步工具的概念、原理以及使用方法。 1. 互斥锁(Mutex Lock): 互斥锁是确保同一时间只有一个线程访问特定...

    windowsC++多线程加锁信号量共享内存

    在"threadlock4"这个文件中,很可能包含了示例代码或者详细教程,演示了如何在Windows环境下使用C++的多线程、互斥锁、信号量和共享内存。通过阅读和理解这个文件,开发者可以学习到如何在实际项目中有效地管理和...

    线程同步(信号量,互斥,条件变量)

    **信号量(Semaphore)**是另一种线程同步工具,它允许有限数量的线程同时访问资源。信号量可以分为二进制信号量(类似于互斥量,只能为0或1,表示资源是否可用)和计数信号量(可设置任意非负整数值,表示资源的...

    标准模板1

    本次实验的主要目标是让学生掌握Linux系统中进程的创建、管理和同步的基本概念与技术,包括fork()、exec()系列函数用于进程创建,wait()、waitpid()用于进程等待,以及信号量semaphore和互斥锁mutex在进程互斥中的...

    Python自学教程-11-互斥锁.ev4.rar

    除了互斥锁,Python的`threading`模块还提供了其他同步机制,如信号量(Semaphore)、事件(Event)、条件变量(Condition)等,它们在特定场景下各有优势。例如,信号量可以控制同时访问某一资源的线程数量,而事件...

Global site tag (gtag.js) - Google Analytics