Java理解线程的例子
摘要:学习看懂这个例子,你就对Java线程有个基本了解了。
先来看看例子:
一辆载西瓜的小货车不幸翻车了,有个人去哄抢(这年头,哎~~~)。假设共10个西瓜,这人每次抢一个西瓜最多花1000ms,当然,他每次抢的时间肯定都不同,所以我们用随机数表示。维护次序者(城管?)2000ms后赶到,随即中断哄抢线程。看这人最后抢到几个西瓜?
看程序:
运行结果:
共10个西瓜
抢到1个西瓜...
抢到2个西瓜...
抢到3个西瓜...
抢到4个西瓜...
抢到5个西瓜...
事件被中断:true
如果多几个人来哄抢呢?再来看看另一个增强例子:
如果有张三、李四和王二麻子三个人同时哄抢呢?这时候,维护次序者1000ms后赶到,随即中断哄抢线程。看这仨赖子最后抢到几个西瓜?
运行结果:
共10个西瓜。
张三加入。
李四加入。
王二加入。
李四抢到本次的第1个西瓜...其共抢到1个西瓜。
张三抢到本次的第2个西瓜...其共抢到1个西瓜。
王二抢到本次的第3个西瓜...其共抢到1个西瓜。
王二抢到本次的第4个西瓜...其共抢到2个西瓜。
王二抢到本次的第5个西瓜...其共抢到3个西瓜。
王二抢到本次的第6个西瓜...其共抢到4个西瓜。
张三抢到本次的第7个西瓜...其共抢到2个西瓜。
李四抢到本次的第8个西瓜...其共抢到2个西瓜。
李四抢到本次的第9个西瓜...其共抢到3个西瓜。
事件被中断:true
事件被中断:true
事件被中断:true
张三共抢到2个西瓜。
李四共抢到3个西瓜。
王二共抢到4个西瓜。
还有1个西瓜未被抢走。
写这段代码蛮有意思的。如果愿意,还可以重构一下会更清晰点。
一辆载西瓜的小货车不幸翻车了,有个人去哄抢(这年头,哎~~~)。假设共10个西瓜,这人每次抢一个西瓜最多花1000ms,当然,他每次抢的时间肯定都不同,所以我们用随机数表示。维护次序者(城管?)2000ms后赶到,随即中断哄抢线程。看这人最后抢到几个西瓜?
看程序:
java代码
import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import static java.lang.System.out; class Looting implements Callable<String> { private int wmQuantities; //西瓜总数 private int milliseconds; //sleep时长的上限 public Looting(int wmQuantities, int milliseconds) { this.wmQuantities = wmQuantities; this.milliseconds = milliseconds; out.println("共" + wmQuantities + "个西瓜"); } @Override public String call() throws Exception { int wmCount = 0; //抢到的西瓜计数 Random random =new Random(); //时长随机数 while(++wmCount <= wmQuantities) { out.println("抢到" + wmCount + "个西瓜..."); Thread.sleep(random.nextInt(milliseconds)); //每次搬抢西瓜所花时间是不同的 } return("本次" + wmQuantities + "个西瓜中,抢了" + (wmCount - 1) + "个。"); } } public class LootWatermelon { public static void main(String[] args) throws Exception, ExecutionException { Looting looting = new Looting(10,1000); ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<String> future = executorService.submit(looting); try { future.get(2000, TimeUnit.MILLISECONDS); //假设维护次序人员2000ms后赶到,中断哄抢线程 out.println("事件正常结束。"); } catch(Exception e) { out.println("事件被中断:" + future.cancel(true)); } executorService.shutdownNow(); //关闭ExecutorService } }
共10个西瓜
抢到1个西瓜...
抢到2个西瓜...
抢到3个西瓜...
抢到4个西瓜...
抢到5个西瓜...
事件被中断:true
如果多几个人来哄抢呢?再来看看另一个增强例子:
如果有张三、李四和王二麻子三个人同时哄抢呢?这时候,维护次序者1000ms后赶到,随即中断哄抢线程。看这仨赖子最后抢到几个西瓜?
java代码
import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import static java.lang.System.out; public class LootWatermelon2 { private static AtomicInteger wmCount = new AtomicInteger(0); //抢到的西瓜计数,这时候改用原子变量 private static int wmQuantities; //西瓜总数 private static int milliseconds; //sleep时长的上限 public LootWatermelon2(int wmQuantities, int milliseconds) { this.wmQuantities = wmQuantities; this.milliseconds = milliseconds; out.println("共" + wmQuantities + "个西瓜。"); } public static class Looting implements Callable<String> { private String someone; //哄抢者 private int someoneWMQuantities = 0; //每个抢到的西瓜总数 public Looting(String someone) { this.someone = someone; out.println(someone + "加入。"); } @Override public String call() throws Exception { Random random =new Random(); //时长随机数 while(wmCount.incrementAndGet() <= wmQuantities) { someoneWMQuantities++; out.println(someone + "抢到本次的第" + wmCount.get() + "个西瓜...其共抢到" + someoneWMQuantities + "个西瓜。"); Thread.sleep(random.nextInt(milliseconds)); //每次搬抢西瓜所花时间是不同的 } return(someone + "共抢到" + someoneWMQuantities + "个西瓜。"); } } public static void main(String[] args) throws Exception, ExecutionException { LootWatermelon2 lootWatermelon2 = new LootWatermelon2(10,1000); Looting looting1 = new Looting("张三"); Looting looting2 = new Looting("李四"); Looting looting3 = new Looting("王二"); ExecutorService executorService = Executors.newFixedThreadPool(3); Future<String> future1 = executorService.submit(looting1); Future<String> future2 = executorService.submit(looting2); Future<String> future3 = executorService.submit(looting3); try { future1.get(1000, TimeUnit.MILLISECONDS); //假设维护次序人员1000ms后赶到,中断哄抢线程 future2.get(1000, TimeUnit.MILLISECONDS); future3.get(1000, TimeUnit.MILLISECONDS); out.println("事件正常结束。"); } catch(Exception e) { out.println("事件被中断:" + future1.cancel(true)); out.println("事件被中断:" + future2.cancel(true)); out.println("事件被中断:" + future3.cancel(true)); } executorService.shutdownNow(); //关闭ExecutorService out.println(looting1.someone + "共抢到" + looting1.someoneWMQuantities + "个西瓜。"); out.println(looting2.someone + "共抢到" + looting2.someoneWMQuantities + "个西瓜。"); out.println(looting3.someone + "共抢到" + looting3.someoneWMQuantities + "个西瓜。"); out.println("还有" + (wmQuantities - looting1.someoneWMQuantities - looting2.someoneWMQuantities - looting3.someoneWMQuantities) + "个西瓜未被抢走。"); } }
共10个西瓜。
张三加入。
李四加入。
王二加入。
李四抢到本次的第1个西瓜...其共抢到1个西瓜。
张三抢到本次的第2个西瓜...其共抢到1个西瓜。
王二抢到本次的第3个西瓜...其共抢到1个西瓜。
王二抢到本次的第4个西瓜...其共抢到2个西瓜。
王二抢到本次的第5个西瓜...其共抢到3个西瓜。
王二抢到本次的第6个西瓜...其共抢到4个西瓜。
张三抢到本次的第7个西瓜...其共抢到2个西瓜。
李四抢到本次的第8个西瓜...其共抢到2个西瓜。
李四抢到本次的第9个西瓜...其共抢到3个西瓜。
事件被中断:true
事件被中断:true
事件被中断:true
张三共抢到2个西瓜。
李四共抢到3个西瓜。
王二共抢到4个西瓜。
还有1个西瓜未被抢走。
写这段代码蛮有意思的。如果愿意,还可以重构一下会更清晰点。
相关文章
最新发布
阅读排行
热门文章
猜你喜欢