信号量场景代码

时间:2017-06-16 06:29:20

标签: java multithreading semaphore

在这种情况下,我试图复制一个真正的ATM机用例,i。在电子银行自助值机亭,我们一次有四台自动柜员机,因此4人(线程)可以一次进行交易。

为此,我使用信号量来实现线程限制限制,但我得到的是不可预测的输出。

 package multithreadinglearning;

import java.time.LocalTime;
import java.util.Scanner;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Semaphore;

 public class ATMSemaphoreExample implements Runnable {

Semaphore sem = new Semaphore(4);
Scanner sc = new Scanner(System.in);
int balance = 1000;

Accounts a;
Accounts b;

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {

    ExecutorService exec = Executors.newFixedThreadPool(10);

    for (int i = 0; i <= 9; i++)
        exec.submit(new ATMSemaphoreExample());
}

@Override
public void run() {

    System.out.println(LocalTime.now() + ":" + Thread.currentThread() + " : acquiring lock...");
    System.out.println(LocalTime.now() + ":" + Thread.currentThread() + " : available Semaphore permits now: "
            + sem.availablePermits());

    try {
        sem.acquire();

        System.out.println(LocalTime.now() + ":" + Thread.currentThread() + " : got the permit...");
        System.out.println(LocalTime.now() + ":" + Thread.currentThread()
                + " : in available Semaphore permits now: " + sem.availablePermits());

        System.out.println("enter sender");
        String sender = sc.next();
        System.out.println("enter reciever");

        String reciver = sc.next();

        a = Bank.getAccount(sender);
        b = Bank.getAccount(reciver);

        System.out.println("a" + a);
        System.out.println("b" + b);

        System.out.println(LocalTime.now() + ":" + "i am " + Thread.currentThread() + "transafering money");

        System.out.println(LocalTime.now() + ":" + Thread.currentThread()
                + " :  inside available Semaphore permits now: " + sem.availablePermits());

        Thread.sleep(5000);
        Accounts.transfer(a, b, 1000);

        System.out.println("balance A:" + a.balance);
        System.out.println("balance B:" + b.balance);

        System.out.println(LocalTime.now() + ":" + Thread.currentThread() + " : releasing lock...");
        sem.release();
        System.out.println(LocalTime.now() + ":" + Thread.currentThread() + " : available Semaphore permits now: "
                + sem.availablePermits());
    } catch (InterruptedException | IllegalArgumentException | IllegalAccessException e) {

        e.printStackTrace();
    }
}
}

以下是我得到的输出:

   11:46:39.888:Thread[pool-1-thread-2,5,main] : acquiring lock...
11:46:39.888:Thread[pool-1-thread-4,5,main] : acquiring lock...
11:46:39.888:Thread[pool-1-thread-1,5,main] : acquiring lock...
11:46:39.888:Thread[pool-1-thread-3,5,main] : acquiring lock...
11:46:39.888:Thread[pool-1-thread-9,5,main] : acquiring lock...
11:46:39.888:Thread[pool-1-thread-3,5,main] : available Semaphore permits 
 now: 4
11:46:39.888:Thread[pool-1-thread-7,5,main] : acquiring lock...
11:46:39.888:Thread[pool-1-thread-6,5,main] : acquiring lock...
11:46:39.888:Thread[pool-1-thread-10,5,main] : acquiring lock...
11:46:39.888:Thread[pool-1-thread-5,5,main] : acquiring lock...
11:46:39.889:Thread[pool-1-thread-10,5,main] : available Semaphore permits 
 now: 4
11:46:39.889:Thread[pool-1-thread-5,5,main] : available Semaphore permits 
 now: 4
11:46:39.888:Thread[pool-1-thread-8,5,main] : acquiring lock...
11:46:39.889:Thread[pool-1-thread-5,5,main] : got the permit...
11:46:39.889:Thread[pool-1-thread-10,5,main] : got the permit...
11:46:39.888:Thread[pool-1-thread-6,5,main] : available Semaphore permits 
 now: 4
11:46:39.888:Thread[pool-1-thread-7,5,main] : available Semaphore permits 
 now: 4
11:46:39.888:Thread[pool-1-thread-3,5,main] : got the permit...
11:46:39.888:Thread[pool-1-thread-9,5,main] : available Semaphore permits 
now: 4
11:46:39.888:Thread[pool-1-thread-1,5,main] : available Semaphore permits 
 now: 4
11:46:39.888:Thread[pool-1-thread-4,5,main] : available Semaphore permits 
 now: 4
11:46:39.888:Thread[pool-1-thread-2,5,main] : available Semaphore permits 
 now: 4
11:46:39.889:Thread[pool-1-thread-4,5,main] : got the permit...
11:46:39.889:Thread[pool-1-thread-1,5,main] : got the permit...
11:46:39.889:Thread[pool-1-thread-9,5,main] : got the permit...
11:46:39.889:Thread[pool-1-thread-3,5,main] : in available Semaphore permits 
 now: 3
11:46:39.889:Thread[pool-1-thread-7,5,main] : got the permit...
11:46:39.889:Thread[pool-1-thread-6,5,main] : got the permit...
11:46:39.889:Thread[pool-1-thread-7,5,main] : in available Semaphore permits 
 now: 3
enter sender
11:46:39.889:Thread[pool-1-thread-10,5,main] : in available Semaphore 
 permits now: 3
enter sender
11:46:39.889:Thread[pool-1-thread-5,5,main] : in available Semaphore permits 
now: 3
enter sender
11:46:39.889:Thread[pool-1-thread-8,5,main] : available Semaphore permits 
 now: 4
11:46:39.889:Thread[pool-1-thread-6,5,main] : in available Semaphore permits 
 now: 3
enter sender
enter sender
11:46:39.889:Thread[pool-1-thread-9,5,main] : in available Semaphore permits 
 now: 3
enter sender
11:46:39.889:Thread[pool-1-thread-1,5,main] : in available Semaphore permits 
 now: 3
enter sender
11:46:39.889:Thread[pool-1-thread-4,5,main] : in available Semaphore permits 
now: 3
enter sender
11:46:39.889:Thread[pool-1-thread-2,5,main] : got the permit...
11:46:39.889:Thread[pool-1-thread-8,5,main] : got the permit...
11:46:39.889:Thread[pool-1-thread-2,5,main] : in available Semaphore permits 
 now: 3
enter sender
11:46:39.889:Thread[pool-1-thread-8,5,main] : in available Semaphore permits 
now: 3
enter sender

在输出中,为什么所有线程都被输入到run()方法的业务代码中并要求用户输入而不是只有4

1 个答案:

答案 0 :(得分:1)

每个可运行的实例(ATMSemaphoreExample)都有自己的信号量。

Semaphore sem = new Semaphore(4);

他们对另一个主题没有任何影响。

将sem声明为静态类型,让所有线程使用相同的信号量实例。

private static Semaphore sem =  new Semaphore(4);

或从主要传递信号量。