`
小懒蛋
  • 浏览: 31459 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

java 线程池与通过Future终止线程实例

    博客分类:
  • java
阅读更多

上周在单位无聊,公司电脑又不能上网,想研究一些swing相关的东西,结果swing没怎么研究,到是写了一个比较坑爹的游戏。


 

 

本人才疏学浅,如有错误请不吝赐教。

另外请尊重别人的劳动成果,如需转载请注明出处:

http://waitingkkk-163-com.iteye.com/blog/2232286

 

 

游戏开始之后,出现此框,鼠标点击到此框即算过关,框框是一直在乱跳的,跳的频率随着关口的靠后会加快。

 

设计思路:

程序加载时new一个frame,不允许frame最大化,但是鼠标滚动可以改变框框的大小(这算一后门),frame中添加一个button,在button中添加两个事件,一个是监听鼠标滚动事件,一个是监听点击事件。

点击事件发生后会改变框框跳动的频率。当累计超过10次被框框逃脱即算失败。

框框跳动的动作在一个单独的线程中进行。

 

所用技术:

1. swing

2. 多线程,线程池,线程终止

 

下面是完整代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.concurrent.*;

/**
 * Created by player on 2015/8/1.
 */
public class CatchMe {

    private static int width = 200;
    private static int length = 200;

    private static Dimension scrSize=Toolkit.getDefaultToolkit().getScreenSize();

    private static int X = (int) (scrSize.getWidth()/2);
    private static int Y = (int) (scrSize.getHeight()/2);

    private static JButton button;
    private static JFrame frame;

    private static int level = 1;

    private static Future<?> task;

    private static ExecutorService pool = Executors.newSingleThreadExecutor();


    static{
        frame = new JFrame();
        frame.setSize(width, length);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocation(X, Y);
        frame.setTitle("catch me ~");
        frame.setResizable(false);
        button = new JButton();
        button.setName("Catch Me");
        button.setText("click to start~");
        frame.add(button);
    }


    public static void main(String args[]){
        addScrollListener();
        addCatchListener();
        frame.setVisible(true);
    }

    private static void addScrollListener(){
        button.addMouseWheelListener(new MouseWheelListener(){
            @Override
            public void mouseWheelMoved(MouseWheelEvent event) {
                int wheelRotation = event.getWheelRotation();
                width += (wheelRotation * event.getScrollAmount());
                length += (wheelRotation * event.getScrollAmount());
                frame.setSize(width, length);
            }
        });
    }

    private static void addCatchListener(){
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                button.setText(String.format("level [%d]", level++));
                if(task == null)
                    task = pool.submit(moveTask);
            }
        });
    }

    private static void loss(){
        //stop
        if(task != null){
            task.cancel(true);
        }
        //show
        button.setText("mission failed at level ["+(level-1)+"]");
        level = 1;
        task = null;
        width = 200;
        length = 200;
        frame.setSize(width, length);
    }

    private static Runnable moveTask = new Runnable() {
        @Override
        public void run() {
            int escape = 0;
            int max = 10;
            while(!Thread.currentThread().isInterrupted()){
                if(escape >= max){
                    loss();
                    escape = 0;
                    break;
                }
                X = (int)(Math.random() * 1000);
                Y = (int)(Math.random() * 800);
                frame.setLocation(X, Y);
                escape ++;
                try {
                    TimeUnit.MILLISECONDS.sleep(3000/level);
                } catch (InterruptedException e) {}
            }
        }
    };

}

 

通过ide的导出功能可以打成一个可执行的jar包,双击一下即可运行,我老婆玩了一下,说这倒霉游戏太坑爹了。

大笑

 

(附件中有我打的jar包)

 

 

关于线程终止可以多说几句鄙人的浅显认识,java线程的终止是非抢占的,这是官方说法,大概是这么说的吧,意思是什么呢,先不管怎么能让一个线程终止,就说你让一个线程终止的时候,线程不会立刻终止,你需要在你的代码中特定的检查点检查“终止状态”,如果状态是“已经终止”线程中的代码就进行相应的处理。

 

关于“终止状态”,可以设置一个变量,比如一个布尔型的flag,默认是true,当需要终止线程的时候把这个变量编程false,那么在线程执行的代码中,比较“重要的点”,检查一下这个状态,如果编程了false就不要往下继续进行了,并可以做一些操作去响应这个终止的信号。

 

关于“重要的点”,这个要根据程序中的逻辑来判断,不可能没句话都检查一下,比如多线程中要做一个打开链接的操作,可能在打开后设置一个检查的点,如果flag变成了false,就不要往下继续进行了,并且要把链接关掉(比如jdbc链接)。(反过来想,如果java线程终止是抢占式的,那岂不是不给咱们机会去关链接了)。

 

有一种特殊情况,阻塞的代码,正在运行的代码可以通过判断状态来处理,如果是阻塞的代码,程序已经卡在那里,无法判断状态,怎么办呢(比如我上面代码中的TimeUnit.MILLISECONDS.sleep(3000/level) 这一行,程序在睡眠的时候如果想要终止程序,不可能一定要等到阻塞的代码恢复后继续走到检查点在去做判断,那样响应时间无法保证),java提供了几种方式终止线程,比如我代码中用的调用Future.cancel(true),这样代码中的阻塞语句如果发现有人调用了取消方法,就会抛出InterruptedException异常,我这里是不需要针对取消操作做什么处理的,如果是需要处理,在catch到异常后可以做善后处理。 

 

还有,我这个程序中的“终止状态”的判断用的是Thread.currentThread().isInterrupted()。

 

 

 

 

 

  • 大小: 18.3 KB
分享到:
评论

相关推荐

    java线程池实例

    Java线程池是一种高效管理线程资源的工具,它通过维护一组可重用的线程来减少创建和销毁线程的开销。在Java中,`java.util.concurrent`包提供了`ExecutorService`接口和它的实现类,如`ThreadPoolExecutor`,来支持...

    JAVA经典线程池源码

    Java线程池是Java并发编程中的重要组成部分,它在多线程编程中扮演着至关重要的角色,有效地管理和调度线程资源,提高了程序的性能和稳定性。本资源包含了一个经典的Java线程池实现,适用于大型项目,能帮助开发者...

    Java 线程池_动力节点Java学院整理

    Java线程池是一种高效管理线程资源的...总的来说,Java线程池是通过合理调度和复用线程,以达到提高系统性能、控制并发数量、简化线程管理的目的。根据应用需求选择合适的线程池类型,可以有效地优化程序的并发性能。

    Java 线程池详解及创建简单实例

    `ExecutorService`扩展了`Executor`,提供了更丰富的线程管理和生命周期控制方法,如`shutdown`、`shutdownNow`用于终止线程池,以及`Future`接口用于获取任务执行结果。 `ThreadPoolExecutor`是`ExecutorService`...

    深入理解高并发编程-Java线程池核心技术

    在深入理解高并发编程,尤其是Java线程池核心技术时,我们首先要明白线程与多线程的概念。线程是操作系统中的基本调度单元,它比进程更小,且基本不拥有系统资源,主要由程序计数器、寄存器和栈等组成。在同一个进程...

    Java多线程编程实例

    总的来说,“Java多线程编程实例”这本书涵盖了Java多线程编程的各个方面,从基础概念到高级用法,包括线程创建、同步机制、线程池、线程通信以及并发工具类的使用,都是现代Java开发者必备的知识。虽然年代久远,但...

    java多线程实例 源码

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,从而提高系统效率和资源利用率。在Java中,实现多线程有两种主要方式:继承Thread类和实现...通过分析和实践这些实例,可以深入掌握Java多线程技术。

    Java多线程下载网络图片

    总之,"Java多线程下载网络图片"这个案例涵盖了多线程编程的多个核心知识点,包括线程创建、同步机制、线程池管理和异常处理等。通过实践这些技术,开发者可以编写出更加高效、稳定、健壮的并发程序。

    JAVA多线程总结

    本篇总结涵盖了Java多线程的基础概念、创建与启动、线程调度、同步与协作以及新特性。 **一、Java线程:概念与原理** 1. **线程与进程**: - **进程**:是操作系统资源分配的基本单位,每个进程都有独立的内存...

    Java线程池,正式上线运行的源码,分享欢迎使用并提意见

    Java线程池是一种高效管理并发任务执行的工具,它通过维护一组可重用的线程,减少了创建和销毁线程的开销。在Java中,`java.util.concurrent`包提供了线程池的相关实现,最核心的类是`ExecutorService`、`...

    java 多线程示例

    通过学习这个实例,你可以掌握如何创建和管理线程,理解线程同步与通信的重要性,以及如何处理线程安全问题。 1. **线程的创建** Java提供了两种创建线程的方式:继承`Thread`类和实现`Runnable`接口。在`lec22`中...

    《Java多线程编程实例》随书源码

    通过《Java多线程编程实例》随书源码,读者可以实际操作这些概念,观察其在不同场景下的应用,例如创建线程池来处理大量并发请求,使用`BlockingQueue`实现生产者消费者模型,或者研究如何避免和解决死锁问题。...

    Java多线程端口快速扫描

    在这个端口扫描程序中,通常会采用实现Runnable接口的方法,因为这样可以避免单继承的限制,同时可以通过Thread类的构造函数创建新的线程实例。 1. **线程的创建与执行** - 实现Runnable接口:创建一个类,实现`...

    JAVA多线程教材

    3. **线程池与ExecutorService**:Java的Executor框架简化了线程管理,通过ThreadPoolExecutor可以创建线程池,这有助于控制系统的资源消耗和提高效率。ScheduledExecutorService则支持定时和周期性任务的执行。 4....

    Java多线程编程经验

    Java 5 引入了 `java.util.concurrent` 包,提供了 `Callable` 和 `Future` 接口,允许线程执行后返回结果。 #### 十四、Java线程:新特征-锁(上) Java 5 还引入了 `java.util.concurrent.locks` 包,提供了比...

    Java多线程编程实例全书随书代码.rar

    《Java多线程编程实例全书》是一本深入探讨Java多线程编程的书籍,它提供了丰富的实例,帮助读者理解并掌握多线程的核心概念和技术。尽管这本书可能相对较老,但其中涉及的知识点仍然是Java开发中不可或缺的部分,...

    多线程实例与ppt教程

    通过这个“多线程实例与PPT教程”,你将能够学习到如何在实际项目中运用多线程技术,了解线程同步的策略,并掌握如何避免和解决线程相关的问题。这将有助于提升你的编程能力和软件设计水平,使你的应用程序更加高效...

Global site tag (gtag.js) - Google Analytics