62,628
社区成员
发帖
与我相关
我的任务
分享package org.imzhs.learn.test;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class App {
static AtomicInteger tokens = new AtomicInteger(100); //初始100个令牌
static Random rnd = new Random();
static CountDownLatch latch; //用来监视线程执行完毕的latch
static class Consumer implements Runnable{
int requireToken(){
while(true){
int currentToken = tokens.get();
if(currentToken >= 20){
int newToken = currentToken - 20;
//CAS更新令牌桶,如果更新失败,证明有其它线程消费Token了,需要重新进行获取尝试
if(tokens.compareAndSet(currentToken, newToken)){
return newToken;
}
}
Thread.yield(); //给予其它线程执行的机会
}
}
int releaseToken(){
return tokens.addAndGet(20);
}
@Override
public void run() {
System.out.println("线程 " + Thread.currentThread().getId() + " 开始执行");
//获取令牌
int currentTokens = requireToken();
System.out.println("线程 " + Thread.currentThread().getId() + " 获取Token,剩余" + currentTokens);
//随机休眠1-2秒,模拟线程执行情况
int sleepSecs = 1 + rnd.nextInt(2);
System.out.println("线程 " + Thread.currentThread().getId() + " 休眠 " + sleepSecs + "秒");
try {
Thread.sleep(sleepSecs * 1000);
} catch (InterruptedException e) {
} finally {
//销毁令牌
currentTokens = releaseToken();
System.out.println("线程 " + Thread.currentThread().getId() + " 释放Token,剩余" + currentTokens);
latch.countDown();
}
}
}
public static void main(String[] args) {
//开始模拟
latch = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
Thread th = new Thread(new Consumer());
th.start();
}
try {
latch.await();//阻塞主线程,直到所有线程执行完毕
} catch (InterruptedException e) {
} finally {
System.out.println("所有线程执行完毕,剩余Token:" + tokens.get()); //此时token数应该为初始容量(100)
}
}
}package org.imzhs.learn.test;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class App {
static AtomicInteger tokens = new AtomicInteger(100); //初始100个令牌
static Random rnd = new Random();
static CountDownLatch latch; //用来监视线程执行完毕的latch
static class Consumer implements Runnable{
int requireToken(){
while(true){
int currentToken = tokens.get();
if(currentToken >= 20){
int newToken = currentToken - 20;
//CAS更新令牌桶,如果更新失败,证明有其它线程消费Token了,需要重新进行获取尝试
if(tokens.compareAndSet(currentToken, newToken)){
return newToken;
}
}
Thread.yield(); //给予其它线程执行的机会
}
}
int releaseToken(){
return tokens.addAndGet(20);
}
@Override
public void run() {
//获取令牌
int currentTokens = requireToken();
System.out.println("线程 " + Thread.currentThread().getId() + " 获取Token,剩余" + currentTokens);
//随机休眠1-2秒,模拟线程执行情况
int sleepSecs = 1 + rnd.nextInt(2);
System.out.println("线程 " + Thread.currentThread().getId() + " 休眠 " + sleepSecs + "秒");
try {
Thread.sleep(sleepSecs * 1000);
} catch (InterruptedException e) {
} finally {
//销毁令牌
currentTokens = releaseToken();
System.out.println("线程 " + Thread.currentThread().getId() + " 释放Token,剩余" + currentTokens);
latch.countDown();
}
}
}
public static void main(String[] args) {
//开始模拟
latch = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
Thread th = new Thread(new Consumer());
th.start();
}
try {
latch.await();//阻塞主线程,直到所有线程执行完毕
} catch (InterruptedException e) {
} finally {
System.out.println("所有线程执行完毕,剩余Token:" + tokens.get()); //此时token数应该为初始容量(100)
}
}
}