java 中的信号量

发布于 2024-10-20 01:36:02 字数 143 浏览 3 评论 0原文

有谁知道如何在 java 中实现基本信号量而不使用 wait()notify()synchronize。我是不是在寻找这个问题的解决方案,只是指向正确方向的指针,因为我完全迷失了这一点。

Has anyone got any idea how to implement a rudimentary semaphore in java without making use of wait(), notify() or synchronize.I am not looking for a solution to this problem just a pointer in the right direction because I amd totally lost on this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

最美的太阳 2024-10-27 01:36:02

几年前我在大学里也做过类似的作业,但是是 C++ 的。对于这种东西来说,Java 是太高级的语言了。

这是我在 C++ 中实现的信号和等待,但我不知道它是否会有帮助,因为您必须实现很多其他事情。

int KernelSem::wait() {
    lock();
    if(--value < 0) {
        PCB::running->state = PCB::BLOCKED;
        PCB::running->waitingAtSem = this;
        blockedQueue->put(PCB::running);
        dispatch();
    }
    else {
        PCB::running->deblockedBy = 0;
        if(semPreempt) dispatch();
    }
    unlock();
    return PCB::running->deblockedBy;
}


void KernelSem::signal() {
    lock();
    if(value++ < 0) {
        PCB* tempPCB = blockedQueue->get();
        if(tempPCB) {
            tempPCB->state = PCB::READY;
            tempPCB->deblockedBy = 0;
            tempPCB->waitingAtSem = 0;
            Scheduler::put(tempPCB);
        }
    }
    if(semPreempt) dispatch();
    unlock();
}

锁定和解锁函数只是 asm{cli}asm{sti} (清除/设置中断标志)。
PCB 是一个流程控制块

希望有帮助

I had similar homework few years ago at my university, but in C++. Java is too high level language for this kind of stuff.

Here is my implementation of signal and wait in C++, but I don't know if it is going to be helpful because you will have to implement a lot of other things.

int KernelSem::wait() {
    lock();
    if(--value < 0) {
        PCB::running->state = PCB::BLOCKED;
        PCB::running->waitingAtSem = this;
        blockedQueue->put(PCB::running);
        dispatch();
    }
    else {
        PCB::running->deblockedBy = 0;
        if(semPreempt) dispatch();
    }
    unlock();
    return PCB::running->deblockedBy;
}


void KernelSem::signal() {
    lock();
    if(value++ < 0) {
        PCB* tempPCB = blockedQueue->get();
        if(tempPCB) {
            tempPCB->state = PCB::READY;
            tempPCB->deblockedBy = 0;
            tempPCB->waitingAtSem = 0;
            Scheduler::put(tempPCB);
        }
    }
    if(semPreempt) dispatch();
    unlock();
}

lock and unlock functions are just asm{cli} and asm{sti} (clear/set interrupt flag).
PCB is a process control block.

Hope it helps

江湖彼岸 2024-10-27 01:36:02

以一种非常简单(又)简单的方式,您可以使用简单的 int 或 boolean 来实现它。

在授予访问权限之前测试 int 或 boolean。如果是 0(厌倦了布尔值),则添加 1 并继续。如果没有,请执行 Thread.yield() 并稍后重试。释放时,将 int 去掉 1 并继续。

幼稚的实现,但效果很好。

in a very simple simple (again) simple way you could implement this using a simple int or boolean.

Test the int or boolean before grant acess. If it is 0 (tired of boolean), add 1 and continue. If not do Thread.yield() and try again latter. When you release, remove 1 from int and continue.

naive implementation, but works fine.

救星 2024-10-27 01:36:02

我希望这是家庭作业,因为我看不出您可能想在生产代码中执行此操作的任何充分理由。维基百科有一个在软件中实现信号量的算法列表。

I hope that this is homework, because I cannot see any good reason you might want to do this in production code. Wikipedia has a list of algorithms for implementing semaphores in software.

浅唱々樱花落 2024-10-27 01:36:02

按照接受的答案中的建议进行操作将导致许多并发问题,因为您无法确保相互排斥。举个例子,两个要求增加一个整数的线程都会同时读取布尔值(建议作为锁),然后两个线程都会认为这是可以的,然后都将布尔值设置为其相反的值。两个线程都会改变东西,当它们完成时,它们都会向(非)互斥变量写入一个值,并且信号量的整个目的就丢失了。 wait() 方法用于等待直到某件事发生,而这正是您想要做的。

如果你绝对不想使用等待,那么实现某种双重检查睡眠技术,其中线程首先检查锁变量,将其更改为 false 并在数组中设置一个标志或专门为该线程设置一个特殊槽的标志以确保它永远成功。然后,线程可以休眠一小段时间,然后检查整个数组中是否有更多标志,以查看是否有其他人同时处于该状态。如果没有,它可以继续,否则它无法继续,并且必须在重试之前休眠一段随机时间(以使线程休眠一段时间以使某人稍后成功)。如果它们再次崩溃,那么它们将随机睡眠更长的时间。该技术也用于无法使用信号量的网络。

(当然,信号量正是您想要做的,但由于它使用等待,我有点假设您想要一些根本不使用等待的东西......)

Doing as proposed in the accepted answer will lead to a lot of concurrent issues as you can't ensure mutual exclusion with this. As an example, two threads asking to increment an integer would both read the boolean (that is proposed as lock) the same time, then both will think it's ok and then both set the bool to its opposite value. Both threads will go in changing stuff and when they are done they will both write a value to the (non)mutually exclusive variable and the whole purpose of the semaphore is lost. The wait() method is for waiting until something happen, and that's exactly what you want to do.

If you absolutely don't want to use wait, then implement some kind of double checking sleep technique where the thread first check the lock variable, changes it to false and sets a flag in an array or something with a special slot just for that thread to ensure that it will always succeed. Then the thread can sleep for a small interval of time and then checks the whole array for more flags to see if someone else were at it the same time. If not, it can continue, else it can't continue and have to sleep for a random amount of time before trying again (to make the threads sleep for lengths to make someone success later). If they collapse again then they will sleep for an even longer random time. This technique is also used in networks where semaphores cannot be used.

(Of course semaphores is exactly what you want to do but as it uses wait i kind of assumed you wanted something that don't use wait at all...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文