Semaphore的使用

释放双眼,带上耳机,听听看~!

Semaphore的作用是控制线程的并发数量。在简单点的解释就是如果我们开始了10个线程都在处理任务,如果我们用到的Semaphore,那么可以让这10个并发任务执行的时候可以只同时执行2个。因为Semaphore的构造方法里需要传递一个int类型的参数,这个参数就是控制线程可以允许的同时并发数。

public class Test {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 1; i <= 3; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int i = 3; i > 0; i--) {
                            System.out.println(String.format("计时:%s	thread: %s", i, Thread.currentThread().getName()));
                            Thread.sleep(3000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                    }
                }
            });
            thread.start();
        }
    }
}
计时:3	thread: Thread-2
计时:3	thread: Thread-1
计时:3	thread: Thread-0
计时:2	thread: Thread-2
计时:2	thread: Thread-0
计时:2	thread: Thread-1
计时:1	thread: Thread-2
计时:1	thread: Thread-0
计时:1	thread: Thread-1

上述代码我们同时开启了3个线程,因为我们没有加同步方法所以这3个开启的线程是异步执行的。那么在实际的任务开发中,如果我们需要控制多线程的并发数量应该怎么办呢?例如我们在操作IO的时候可能会因为系统的内存或者磁盘等因素,导致我们的CPU占有率很高,这时我们就要调整线程的同时并发数,否则系统可能会卡死。这时我们就会用到Semaphore。它的使用方法也比较简单,当调用acquire()方法时,就是会获取由Semaphore颁发的许可证,当调用release()方法时就会把获取的许可证归还。Semaphore中的许可证数量是由创建Semaphore对象的构造方法的参数决定的。参数值是多少,就有多少个许可证,有多少个许可证,就可以同时有多少个线程并发执行,因为没有获得许可证的线程则不会执行。

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Semaphore semaphore = new Semaphore(2);
        for (int i = 1; i <= 3; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore.acquire();
                        for (int i = 3; i > 0; i--) {
                            System.out.println(String.format("计时:%s	thread: %s", i, Thread.currentThread().getName()));
                            Thread.sleep(3000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        semaphore.release();
                    }
                }
            });
            thread.start();
        }
    }
}
计时:3	thread: Thread-0
计时:3	thread: Thread-1
计时:2	thread: Thread-0
计时:2	thread: Thread-1
计时:1	thread: Thread-0
计时:1	thread: Thread-1
计时:3	thread: Thread-2
计时:2	thread: Thread-2
计时:1	thread: Thread-2

我们看输出虽然我们开启了3个线程,但同时执行的线程任务只有2个,原因就是我们设置的Semaphore构造函数的参数为2。也就是说同时执行的任务只能是2个,如果有一个线程的任务已经执行完了,那么另一个线程才会执行。原因是上一个线程已经将许可证归还了,当前线程可以重新获取到许可证了。

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧