多线程的问题

太上-道 2017-03-19 03:04:45
求大神给个代码,有100,每次让子线程执行20,执行完后再次分配给子线程20,直到没有!

...全文
224 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
zs808 2017-03-20
  • 打赏
  • 举报
回复
为了更直观点,在线程开始执行的时候加了一个print,代码如下:
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)
		}
	}
}
zs808 2017-03-20
  • 打赏
  • 举报
回复
你说的是令牌桶(Token Bucket)的实现吧。 下面是一个最简单的示例实现:
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)
		}
	}
}

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧