了解信号量......

时间:2013-12-24 13:24:13

标签: java multithreading

我在这里有一个代码,用于解释信号量是如何工作的。无论我怎么努力,我都不理解下面这一行,并且有关如何调用信号量的信息。

基本上代码试图模拟许多连接......

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。令人惊讶,但从未发生过。

2 个答案:

答案 0 :(得分:2)

Semaphore用于获取锁,并执行一些代码然后最终释放锁。

在你的代码中也发生了同样的事情。

  1. sem.acquire();将获得锁定。
  2. doConnect(); //在此处编写代码。
  3. sem.release();释放锁定。
  4. 有关详细信息,请参阅 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();
    }
}