在这种情况下,我试图复制一个真正的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 。
答案 0 :(得分:1)
每个可运行的实例(ATMSemaphoreExample)都有自己的信号量。
Semaphore sem = new Semaphore(4);
他们对另一个主题没有任何影响。
将sem声明为静态类型,让所有线程使用相同的信号量实例。
private static Semaphore sem = new Semaphore(4);
或从主要传递信号量。