模拟多个线程前往一个容量为2的电影院,使用信号量。

huangapple 未分类评论47阅读模式
标题翻译

Simulated Persons / thread going to a cinema hall with capacity 2 using semaphore

问题

我了解了Semaphore,计数信号量,根据文档,它的目标是在同一时间多个线程授予对某个共享资源的访问权。

我尝试在线搜索一个具体的例子,但没有找到。

我想到了一个场景,其中有人/线程正在观看电影。现在,电影院可以模拟一个共享资源,可以被多个人、线程同时使用。我认为这将是一个很好的例子。

在这个探索中,我创建了下面的程序。

Entry.java

package com.example.threads.semaphore.second.v2;

import java.util.concurrent.Semaphore;

// 这是想要观看电影的线程的主要“入口”
public class Entry {

    // 计数信号量,容量为2
    // 这意味着最多有2个人/线程可以进入影院
    private Semaphore available = new Semaphore(2, true);

    private MovieWatching mw = new MovieWatching(available);

    // 这个方法将允许人员进入电影院
    // 首先尝试获取信号量

    // 人员离开影院的逻辑
    // 取决于人员本身,在主线程中设置,
    // 标志->“moveOut”

    public void access(Person p) throws InterruptedException {

        // 这将消耗一个许可
        available.acquire();

        System.out.println("Person " + p + " 允许进入影院");
        mw.watchMovie(p);
    }
}

Person.java

package com.example.threads.semaphore.second.v2;

public class Person implements Runnable {

    // 这个线程本地变量将用于让
    // 人员离开电影院,从而其他
    // 人员可以进入正在尝试获取信号量的电影院。

    // 这里,影院表示一个共享资源。

    private Entry entry;

    public Person(Entry entry) {
        this.entry = entry;
    }

    // 这个字段需要是volatile的,因为这个字段
    // 在主线程中被更新。

    // 当这不被保持为volatile时,这会模拟字段可见性问题,
    // 在这种情况下,MovieWatching()方法中的无限循环
    // 永远不会退出。
    private volatile Boolean moveOut = new Boolean(false);

    public Boolean getMoveOut() {
        return moveOut;
    }

    public void setMoveOut(Boolean moveOut) {
        this.moveOut = moveOut;
    }

    @Override
    public void run() {
        try {
            entry.access(this);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

MovieWatching.java:它代表观影/剧院。

package com.example.threads.semaphore.second.v2;

import java.util.concurrent.Semaphore;

public class MovieWatching {

    private Semaphore available;

    public MovieWatching(Semaphore available) {

        this.available = available;
    }

    public void watchMovie(Person p) {

        for (; !p.getMoveOut();) {
            // 观影活动
            // 除非人员决定在中途离开
            // 人员将继续观看电影。
        }
        System.out.println("Person " + p + " 现在走出去了");

        // 现在,为想要观看电影的其他等待线程腾出位置
        // 它们在入口处等待。
        available.release();
    }
}

MainDemo.java:主入口点。

package com.example.threads.semaphore.second.v2;

public class MainDemo {

    public static void main(String[] args) throws InterruptedException {

        Entry entry = new Entry();

        Person p1 = new Person(entry);
        Person p2 = new Person(entry);
        Person p3 = new Person(entry);

        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(p2);
        Thread t3 = new Thread(p3);

        t1.start();
        t2.start();

        // 确保t1和t2进入
        // 影院。
        Thread.sleep(1000);
        t3.start();

        Thread.sleep(10000);

        p1.setMoveOut(true);

        t1.join();
        t2.join();
        t3.join();
    }
}

这个程序似乎按照我预期的工作,是一个示例例子:

Person com.example.threads.semaphore.second.v2.Person@67ac2678 允许进入影院
Person com.example.threads.semaphore.second.v2.Person@2204de0a 允许进入影院
Person com.example.threads.semaphore.second.v2.Person@67ac2678 现在走出去了
Person com.example.threads.semaphore.second.v2.Person@7b2d84bd 允许进入影院

我第一次使用了Semaphore,所以想请教专家,这是Semaphore预期执行的操作,我的实现是否正确(模拟了Semaphore为一个共享资源授予多个线程访问权限)。

英文翻译

I read about Semaphore , Counting Semaphore and based on the documentation, it says aim of Semaphore is to grant access to multiple threads to some shared resource, at the same time.

I tried to search online for a concrete example, but didn't find any.

I thought of a scenario, in which Person / thread watching movie. Now, Cinema hall can simulate a shared resource , which can be used by multiple persons , threads at the same time. I felt this would be a good example, to being with.

In this quest, I created the below program.

Entry.java

package com.example.threads.semaphore.second.v2;

import java.util.concurrent.Semaphore;

// This is the main "Entry" for thread
// which want to watch movie.
public class Entry {

    // Counting semaphore, with capacity 2
    // which means at most, 2 persons/ threads
    // will go into threatre.
    private Semaphore available = new Semaphore(2, true);

    private MovieWatching mw = new MovieWatching(available);

    // This method will allow person to go inside Cinema hall
    // by first trying to acquire semaphore.

    // The logic of person getting out of theatre
    // is dependent upon the Person itself, which we set in Main thread,
    // The flag -> "moveOut"

    public void access(Person p) throws InterruptedException {

        // This will consume a permit.
        available.acquire();

        System.out.println("Person " + p + " allowed to inside theatre");
        mw.watchMovie(p);
    }
}

Person.java

package com.example.threads.semaphore.second.v2;

public class Person implements Runnable {

    // This thread local would be used to make
    // person go out of theatre, and thus other
    // person can go inside the Theatre, who are trying to acquire a Semaphore.

    // Here Theatre represents a shared resource.

    private Entry entry;

    public Person(Entry entry) {
        this.entry = entry;
    }

    // This needs to be volatile as this field
    // is being update in main thread.

    // This simulated field visibility problem
    // when this isn't kept as volatile, then
    // the for(;;) loop in MovieWatching() mehthod
    // never comes out.
    private volatile Boolean moveOut = new Boolean(false);

    public Boolean getMoveOut() {
        return moveOut;
    }

    public void setMoveOut(Boolean moveOut) {
        this.moveOut = moveOut;
    }

    @Override
    public void run() {
        try {
            entry.access(this);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

MovieWatching.java: It represent threatre/movie watching.

package com.example.threads.semaphore.second.v2;

import java.util.concurrent.Semaphore;

public class MovieWatching {

    private Semaphore available;

    public MovieWatching(Semaphore available) {

        this.available = available;
    }

    public void watchMovie(Person p) {

        for (; !p.getMoveOut();) {
            // Movie watcing activity
            // unless person decides to go in the middle
            // the person will keep watching movie.

        }
        System.out.println("Person " + p + " going out now");

        // Now, make room for other waiting threads
        // who want to watch movie, waiting at Entry.
        available.release();
    }
}

MainDemo.java: Main entry point.

package com.example.threads.semaphore.second.v2;

public class MainDemo {

    public static void main(String[] args) throws InterruptedException {

        Entry entry = new Entry();

        Person p1 = new Person(entry);
        Person p2 = new Person(entry);
        Person p3 = new Person(entry);

        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(p2);
        Thread t3 = new Thread(p3);

        t1.start();
        t2.start();

        // Making sure that t1 and t2 gets
        // into theatre.
        Thread.sleep(1000);
        t3.start();

        Thread.sleep(10000);

        p1.setMoveOut(true);

        t1.join();
        t2.join();
        t3.join();
    }
}

This program seems to be working, a I expected, a sample example:

Person com.example.threads.semaphore.second.v2.Person@67ac2678 allowed to inside theatre
Person com.example.threads.semaphore.second.v2.Person@2204de0a allowed to inside theatre
Person com.example.threads.semaphore.second.v2.Person@67ac2678 going out now
Person com.example.threads.semaphore.second.v2.Person@7b2d84bd allowed to inside theatre

I have used Semaphore maiden time, so want to ask experts if this is what Semaphore is expected to do, and is my implementation correct (to simulate Semaphore granting access to multiple threads for a shared resource)

huangapple
  • 本文由 发表于 2020年5月30日 19:53:56
  • 转载请务必保留本文链接:https://java.coder-hub.com/62102043.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定