目录
引出
Java多线程——信号量Semaphore是啥
信号量Semaphore ?
Semaphore 通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。线程限流,如连接池、停车场。
public class App11 {
public static void main(String[] args) throws InterruptedException {
//1. 创建信号量设置并发线程数,允许最大并发线程数是3
Semaphore semaphore = new Semaphore(3);
//2. 循环创建6个线程,会看到每次执行3个线程
for (int i = 0; i < 6; i++) {
new Thread(() -> {
try {
//3. 获取许可,在达到限制并发线程数之前将可以正常执行线程;否则要等待其他线程释放许可
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + ":进入停车场");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + ":离开停车场");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//4. 释放许可
semaphore.release();
}
}, "车辆" + i).start();
}
}
}
在上述示例中,Semaphore
用于限制同时可以获取许可的线程数量。每个线程在执行前通过 semaphore.acquire()
获取一个许可,执行后通过 semaphore.release()
释放许可。这样,最多只有指定数量的线程可以同时访问资源,其他线程需要等待。
创建线程有几种方式?
方式1:继承Thread创建线程
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start();
MyThread t2 = new MyThread();
t2.start();
}
}
方式2:通过Runnable
public class App2 {
public static void main(String[] args) {
new Thread(()->{
for (int i = 0; i < 20; i++) {
System.out.println("i = " + i);
}
}).start();
}
}
方式3:通过Callable创建线程
一个可取消的异步计算。FutureTask提供了对Future的基本实现,可以调用方法去开始和取消一个计算,可以查询计算是否完成并且获取计算结果。只有当计算完成时才能获取到计算结果,一旦计算完成,计算将不能被重启或者被取消,除非调用runAndReset方法。
总的来说,如果你需要在线程任务执行完毕后获取返回结果,或者需要在任务中处理受检查异常,那么你应该使用 Callable
接口。如果你只需要执行一个简单的线程任务而不关心返回结果,那么使用 Runnable
接口更加合适。
package cn.test;
import java.util.concurrent.*;
public