java 多线程

Semaphore的应用场景与使用实例

在停车场中有5个停车位,现有十辆车想进入停车场,每辆车最多停留 1000 ms,每辆车随机抢占车位,但要保证一个车位只有一辆车

Semaphore 是信号量,内部有一个成员变量int state,调用acquire()方法,如果state大于0,将state减一,如果state不大于0,会阻塞,直到其他线程调用release()方法,将state加一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class CarPark {
public static void main(String[] args) {
BlockingQueue<Integer> parks = new LinkedBlockingQueue<>(5);
for (int i=0; i<5; i++)
parks.offer(i);
Semaphore semaphore = new Semaphore(5);
List<Thread> list = new ArrayList<>();
for (int i=0; i<10; i++) {
list.add(new Thread(()->{
try {
// 占用车位
semaphore.acquire();
int parkNum = parks.take();
System.out.println(parkNum);
Thread.sleep(2000);
// 释放车位
parks.offer(parkNum);
semaphore.release();
} catch (Exception e) {
e.printStackTrace();
}
}));
}
for (Thread t : list) {
t.start();
}
}
}

ThreadLocal 的应用场景与使用实例

有三个用户,服务器要为每个登陆的用户创建一个线程,如果当天登陆了就将登陆次数加一;

ThreadLocal可以让共享变量对每个线程都是内部的,各个线程之间的是相互独立的,不会相互影响;实现原理简单的说:是ThreadLocal内有一个线程安全的 map,线程的 id 作为 key,实例对象为 value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class LoginTimeLogs {
private static ThreadLocal<Integer> loginTimeInMonth = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return Integer.valueOf(0);
}
};
public static void main(String[] args) {
for (int i=0; i<3; i++) {
new Thread(()->{
// 假设每个用户都是每天都登陆
for (int j=1; j<=7; j++) {
loginTimeInMonth.set(loginTimeInMonth.get()+1);
System.out.println(Thread.currentThread().getName() + " " + loginTimeInMonth.get());
}
}, "t"+i).start();
}
}
}
您的支持鼓励我继续创作!