`
songlei8090
  • 浏览: 39295 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java理解线程的例子

 
阅读更多

先来看看例子:

一辆载西瓜的小货车不幸翻车了,有个人去哄抢(这年头,哎~~~)。假设共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个西瓜未被抢走。
写这段代码蛮有意思的。如果愿意,还可以重构一下会更清晰点。

2
0
分享到:
评论
2 楼 long3ok 2014-10-30  
西瓜有漏抢和同时被多个人抢到的情况
1 楼 houyujiangjun 2014-10-30  
有点意思 

相关推荐

    java多线程经典例子

    在Java多线程编程中,理解如何创建和管理线程是至关重要的。在这个经典例子中,我们看到两种创建线程的方式:通过继承`Thread`类和实现`Runnable`接口。 首先,我们创建了一个名为`ThreadUseExtends`的类,它直接...

    java中线程的应用例子

    总的来说,理解和掌握Java中的线程应用是成为熟练Java开发者的关键一步。通过合理地使用线程,可以优化程序性能,提高用户体验。在实际项目中,务必关注线程安全和同步,避免出现竞态条件和死锁等问题,同时注意合理...

    java一个多线程的经典例子

    根据提供的文件信息,我们可以归纳出以下关于Java多线程的经典示例中的关键知识点: ### Java多线程实现方式 在Java中,实现多线程有...通过这些知识点的学习,可以更好地理解和掌握Java多线程的基本原理和使用方法。

    java 多线程小例子 很方便 很实用 适合初学者

    ### Java多线程小例子详解 #### 知识点一:基本多线程示例 在给定的代码示例中,我们首先看到的是一个简单的Java多线程应用实例。这个例子展示了如何创建并启动一个新的线程。在`ThreadDemo`类的`main`方法中,...

    java多线程示例

    在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应...文档“java多线程实例.docx”可能包含具体的示例代码和详细解释,建议参考学习,以加深对Java多线程的理解。

    java 多线程例子

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,从而...理解并熟练掌握这些知识点对于编写高效、安全的多线程程序至关重要。在实际应用中,还需要考虑线程安全、死锁等问题,确保程序的稳定性和性能。

    java多线程经典案例

    通过分析并实践`threadTest`案例,我们可以深入理解Java多线程的原理和使用技巧,为编写高效并发程序打下坚实基础。同时,也要注意多线程编程中的死锁、活锁和饥饿等问题,合理设计线程间的交互,避免出现不可预期的...

    java多线程编程-详细炒作例子

    #### 理解多线程概念与Java内存模型 多线程,作为现代编程中的一项关键技术,允许在单一应用程序中并发执行多个指令流,每个这样的指令流被称为一个线程。在Java中,线程被视为轻量级进程,与进程相似,它们拥有...

    java多线程例子.doc

    理解并熟练掌握这些线程方法对于编写高效、可靠的多线程程序至关重要。在实际开发中,合理地使用线程管理方法能够提高程序的并发性能,同时减少潜在的竞态条件、死锁等问题。因此,深入学习和实践Java多线程编程对于...

    JAVA单线程多线程

    #### 单线程的理解 在Java编程环境中,单线程指的是程序执行过程中只有一个线程在运行。这意味着任何时刻只能执行一个任务,上一个任务完成后才会进行下一个任务。单线程模型简化了程序设计,降低了程序复杂度,...

    一个简单的线程例子

    在这个简单的线程例子中,我们将深入理解线程的概念、如何创建和管理线程,以及它们在多任务处理中的作用。 线程是操作系统分配CPU时间片的基本单位,它们共享同一进程的资源,如内存空间和文件句柄,但拥有独立的...

    JAVA多线程的一个带UI界面的例子

    在Java编程中,多线程是一项关键特性,...总之,这个"JAVA多线程的一个带UI界面的例子"涵盖了Java多线程编程和GUI设计的核心概念,通过实际的代码示例,有助于开发者深入理解如何在实际应用中正确、高效地使用多线程。

    java多线程代码案例(创建线程,主线程,线程优先级,线程组,线程同步,线程间的通信)

    这些知识点都是Java多线程编程的基础,理解并熟练运用它们能帮助开发者编写高效、安全的多线程程序。在实际开发中,还应考虑线程池的使用,以提高系统性能和资源利用率。通过阅读和分析提供的`java多线程的案例源...

    java线程例子程序

    本示例程序"java线程例子程序"展示了如何启动并管理多个线程,同时计算它们的运行时间和总挂起时间。 首先,我们来看`ThreadPrj.java`,这个文件很可能包含了线程类的定义。在这个类中,通常会重写`run()`方法,该...

    Java 多线程 订票 示例 线程安全

    首先,我们要理解什么是线程安全。线程安全是指当多个线程访问同一代码块时,即使这些线程是并发执行的,程序也能保持其正确性,即不会出现数据混乱或丢失的情况。在Java中,实现线程安全的方法通常包括同步机制...

    java多线程例子-生产者消费者

    在本示例中,“java多线程例子-生产者消费者”旨在展示如何利用多线程来实现生产者和消费者模式。这种模式是并发编程中的经典设计模式,用于协调生产数据和消费数据的两个不同线程。 生产者消费者模式的基本概念是...

    java多线程例子!.doc

    总的来说,Java多线程编程涉及线程的创建、同步、通信和管理,理解并熟练掌握这些知识点对于编写高效、安全的并发代码至关重要。在实际应用中,需要根据具体需求选择合适的线程模型和同步策略,以优化性能和避免并发...

    java线程例子大全

    本资源“java线程例子大全”包含了十八个单元的实例代码,覆盖了Java线程操作的多个方面。 1. **线程创建** - 继承`Thread`类:创建一个新的类,该类继承自`Thread`,然后重写`run()`方法。实例化后调用`start()`...

    Java多线程实现异步调用实例

    在本实例中,我们将深入探讨如何使用Java实现多线程以实现异步调用,并理解其背后的机制。 首先,多线程允许一个程序同时执行多个任务。在Java中,我们可以通过继承`Thread`类或实现`Runnable`接口来创建线程。在这...

    Java多线程例子分析 消费者的协作程序.doc

    这个例子展示了如何在Java中实现多线程的协作,以及如何利用同步机制(如wait()和notifyAll())来控制线程的执行顺序和资源共享。此外,它还强调了线程安全的实现,防止了数据竞争问题。理解这个模型有助于开发者在...

Global site tag (gtag.js) - Google Analytics