先来看看例子:
一辆载西瓜的小货车不幸翻车了,有个人去哄抢(这年头,哎~~~)。假设共10个西瓜,这人每次抢一个西瓜最多花1000ms,当然,他每次抢的时间肯定都不同,所以我们用随机数表示。维护次序者(城管?)2000ms后赶到,随即中断哄抢线程。看这人最后抢到几个西瓜?
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后赶到,随即中断哄抢线程。看这仨赖子最后抢到几个西瓜?
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个西瓜未被抢走。
写这段代码蛮有意思的。如果愿意,还可以重构一下会更清晰点。
相关推荐
在Java多线程编程中,理解如何创建和管理线程是至关重要的。在这个经典例子中,我们看到两种创建线程的方式:通过继承`Thread`类和实现`Runnable`接口。 首先,我们创建了一个名为`ThreadUseExtends`的类,它直接...
总的来说,理解和掌握Java中的线程应用是成为熟练Java开发者的关键一步。通过合理地使用线程,可以优化程序性能,提高用户体验。在实际项目中,务必关注线程安全和同步,避免出现竞态条件和死锁等问题,同时注意合理...
根据提供的文件信息,我们可以归纳出以下关于Java多线程的经典示例中的关键知识点: ### Java多线程实现方式 在Java中,实现多线程有...通过这些知识点的学习,可以更好地理解和掌握Java多线程的基本原理和使用方法。
### Java多线程小例子详解 #### 知识点一:基本多线程示例 在给定的代码示例中,我们首先看到的是一个简单的Java多线程应用实例。这个例子展示了如何创建并启动一个新的线程。在`ThreadDemo`类的`main`方法中,...
在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应...文档“java多线程实例.docx”可能包含具体的示例代码和详细解释,建议参考学习,以加深对Java多线程的理解。
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,从而...理解并熟练掌握这些知识点对于编写高效、安全的多线程程序至关重要。在实际应用中,还需要考虑线程安全、死锁等问题,确保程序的稳定性和性能。
通过分析并实践`threadTest`案例,我们可以深入理解Java多线程的原理和使用技巧,为编写高效并发程序打下坚实基础。同时,也要注意多线程编程中的死锁、活锁和饥饿等问题,合理设计线程间的交互,避免出现不可预期的...
#### 理解多线程概念与Java内存模型 多线程,作为现代编程中的一项关键技术,允许在单一应用程序中并发执行多个指令流,每个这样的指令流被称为一个线程。在Java中,线程被视为轻量级进程,与进程相似,它们拥有...
理解并熟练掌握这些线程方法对于编写高效、可靠的多线程程序至关重要。在实际开发中,合理地使用线程管理方法能够提高程序的并发性能,同时减少潜在的竞态条件、死锁等问题。因此,深入学习和实践Java多线程编程对于...
#### 单线程的理解 在Java编程环境中,单线程指的是程序执行过程中只有一个线程在运行。这意味着任何时刻只能执行一个任务,上一个任务完成后才会进行下一个任务。单线程模型简化了程序设计,降低了程序复杂度,...
在这个简单的线程例子中,我们将深入理解线程的概念、如何创建和管理线程,以及它们在多任务处理中的作用。 线程是操作系统分配CPU时间片的基本单位,它们共享同一进程的资源,如内存空间和文件句柄,但拥有独立的...
在Java编程中,多线程是一项关键特性,...总之,这个"JAVA多线程的一个带UI界面的例子"涵盖了Java多线程编程和GUI设计的核心概念,通过实际的代码示例,有助于开发者深入理解如何在实际应用中正确、高效地使用多线程。
这些知识点都是Java多线程编程的基础,理解并熟练运用它们能帮助开发者编写高效、安全的多线程程序。在实际开发中,还应考虑线程池的使用,以提高系统性能和资源利用率。通过阅读和分析提供的`java多线程的案例源...
本示例程序"java线程例子程序"展示了如何启动并管理多个线程,同时计算它们的运行时间和总挂起时间。 首先,我们来看`ThreadPrj.java`,这个文件很可能包含了线程类的定义。在这个类中,通常会重写`run()`方法,该...
首先,我们要理解什么是线程安全。线程安全是指当多个线程访问同一代码块时,即使这些线程是并发执行的,程序也能保持其正确性,即不会出现数据混乱或丢失的情况。在Java中,实现线程安全的方法通常包括同步机制...
在本示例中,“java多线程例子-生产者消费者”旨在展示如何利用多线程来实现生产者和消费者模式。这种模式是并发编程中的经典设计模式,用于协调生产数据和消费数据的两个不同线程。 生产者消费者模式的基本概念是...
总的来说,Java多线程编程涉及线程的创建、同步、通信和管理,理解并熟练掌握这些知识点对于编写高效、安全的并发代码至关重要。在实际应用中,需要根据具体需求选择合适的线程模型和同步策略,以优化性能和避免并发...
本资源“java线程例子大全”包含了十八个单元的实例代码,覆盖了Java线程操作的多个方面。 1. **线程创建** - 继承`Thread`类:创建一个新的类,该类继承自`Thread`,然后重写`run()`方法。实例化后调用`start()`...
在本实例中,我们将深入探讨如何使用Java实现多线程以实现异步调用,并理解其背后的机制。 首先,多线程允许一个程序同时执行多个任务。在Java中,我们可以通过继承`Thread`类或实现`Runnable`接口来创建线程。在这...
这个例子展示了如何在Java中实现多线程的协作,以及如何利用同步机制(如wait()和notifyAll())来控制线程的执行顺序和资源共享。此外,它还强调了线程安全的实现,防止了数据竞争问题。理解这个模型有助于开发者在...