我在这里有一个代码,用于解释信号量是如何工作的。无论我怎么努力,我都不理解下面这一行,并且有关如何调用信号量的信息。
基本上代码试图模拟许多连接......
import java.util.concurrent.Semaphore;
public class Connection {
private static Connection instance = new Connection();
private Semaphore sem = new Semaphore(10, true);
private int connections = 0;
private Connection() {
}
public static Connection getInstance() {
return instance;
}
public void connect() {
try {
sem.acquire();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
doConnect();
} finally {
sem.release();
}
}
public void doConnect() {
synchronized (this) {
connections++;
System.out.println("Current connections: " + connections);
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (this) {
connections--;
}
}
}
主类文件..
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class App {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newCachedThreadPool();
for(int i=0; i < 200; i++) {
executor.submit(new Runnable() {
public void run() {
Connection.getInstance().connect();
}
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.DAYS);
}
}
我不了解跑步部分
public void run() {
Connection.getInstance().connect();
}
我们如何从上面调用connect方法?在我的判断中,当调用新线程时,连接输出应始终为1。令人惊讶,但从未发生过。
答案 0 :(得分:2)
Semaphore用于获取锁,并执行一些代码然后最终释放锁。
在你的代码中也发生了同样的事情。
sem.acquire();
将获得锁定。 doConnect();
//在此处编写代码。sem.release();
释放锁定。有关详细信息,请参阅 this 。
答案 1 :(得分:2)
我会试着解释那里发生的事情。以下代码在每个单独的线程中运行,因为您将其提交到线程池:
public void run() {
Connection.getInstance().connect();
}
Connection.getInstance()
这里返回一个单例(一个对象Connection
的单个实例,它在线程之间共享,更多:What is an efficient way to implement a singleton pattern in Java?)。这个单例包含一个信号量,它也是单个信号并在线程之间共享。因此,在这种情况下,这种技术的全部目的是在多个线程之间共享一个信号量。
connect()
:
public void connect() {
try {
// this acquires a single permit for a shared semaphore,
// so no more than 10 threads (the result of new Semaphore(10, true))
// will enter the critical section below simultaneously
sem.acquire();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
// the critical section, at this point there will be 10 threads at max
// this is the purpose of the semaphore
doConnect();
} finally {
// returns the permit acquired, so that a one more thread may
// enter the critical section
sem.release();
}
}