0 0

java线程 如何监控用户操作超时20

正在写一个简易银行卡管理程序,基本功能已经完成,现在想要完成的是:
当用户1分钟内没有操作的话,就弹出警告对话框,然后自动logout!

相关的类主要有:MainFrame.java(主界面、JFrame)、ValidateUser.java(JPanel,已添加到MainFrame的contentPane上)、其它功能(存、取款、查询、转账等,也都是JPanel)


我目前的想法是:

MainFrame中写一个后台线程(名字是:timeLimited,我把它设置为了public static,以便在ValidateUser中执行操作)(设一个变量operTime=60,线程运行时,不断重复operTime--、TimeUnit.SECONDS.sleep(1);直到为0,强制logout)

监视用户操作(主要是按钮、文本框输入,MainFrame中一旦有actionPerformed、keyPressed操作,就让线程wait();一旦有keyReleased,就notify,重新计时)

ValidateUser中的登录、logout按钮也要实现对此记时线程的控制


由于对线程、锁的概念掌握还不好,用的语句都是timeLimited.wait();timeLimited.notify();(我知道这样不对,但不知道具体怎么改)  

运行时产生异常:
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at Main.MainFrame.monitorWait(MainFrame.java:215)
at Main.MainFrame$operateLimited.run(MainFrame.java:72)
at java.lang.Thread.run(Thread.java:619)

求教:如何解决问题?!谢谢……(最好能给出线程相关的代码)

问题补充:
zhao3546 写道
这个问题实际可以通过这样的方法来实现。

在打开主界面后,就设置一个定时器(java.util.timer),该定时器的作用就是在1分钟弹出对话框“提示用户操作超时”;

java.util.Timer timer = new java.util.Timer();
timer.schedule(new java.util.TimerTask() {
	@Override
	public void run() {
		// 触发事件,弹出对话框“提示用户操作超时”
		// TODO 请自行实现
	}
}, 60000);


当用户进行了某种操作,则取消定时器,并重新设置定时器。
timer.cancel();


这个方法可行,但还是问一句:怎么去响应用户操作?

我的主界面:MainFrame extends JFrame implements MouseListener, KeyListener

构造器内:addMouseListener(this);addKeyListener(this);

在keyPressed、mousePressed方法内:timer.cancel();
keyReleased、mouseReleased方法内:新建一个同样的Timer,执行;

可是运行结果是(我设置的是5秒钟就超时):根本没有响应,一过5秒就弹出警告了……求教!^_^#



问题补充:
zhao3546 写道
在keyPressed、mousePressed方法内:timer.cancel();
keyReleased、mouseReleased方法内:新建一个同样的Timer,执行;

有一点需要说明:
上面对应的代码中的 timer 必须是同一个timer对象,否则得不到你要的结果。

我的意思是……在MainFrame界面中无法监听键盘事件、以及面板上按钮的action事件……

问题补充:
zhao3546 写道
这个问题你可以参考一下实际的ATM。

在用户不插入卡时,ATM一直显示欢迎画面(可能是广告等);
在用户插入卡后,这时ATM的画面就会发生变化。

对应你的程序,应该上也应该有这样的类似事件。比如用户按了某个按钮或输入某个快捷键,这时应该设置对应的timer了。当用户再进行某个操作,则取消之前的timer,并新设置一个timer。一直这样下去,直到用户正常操作结束,或timer超时。

用户操作正常结束或timer超时后,则ATM又重新进入欢迎画面。


首先多谢你的热心帮助!^_^  也许是我没表达清楚:业务逻辑我都实现了,已经没问题,定时器的写法也实现了要求!(是按照你说的那样,可以完成!但是只能响应鼠标的点击)

我现在的问题是:不知道怎么让整个主界面响应键盘事件、按钮事件(MainFrame extends JFrame implements MouseListener, KeyListener   这样写貌似没用!)

网上也有人问这种问题,可惜就是没人给出答案……

问题补充:
netchick 写道
GlassPane

我以前试过了……但是:一旦加上GlassPane,面板上的组件都无法接收到事件了!就算是把组件都放到GlassPane上,这跟不加它有何区别,感觉像多此一举……(这个没试,感觉是这样的。)如果可行,能否给个简单的示意性代码……
2010年4月10日 10:39

9个答案 按时间排序 按投票排序

0 0

我觉得可以写一个线程类,设置属性时间time=60,在run方法里:
while(time != 0){
     Thread.sleep(1000);
     time --;
}
----其他退出或则提示操作。


每次有按键或则输入操作的时候   调用setTime(60);


不知道这样行不呢? 

2010年4月21日 15:08
0 0

GlassPane

2010年4月20日 16:47
0 0

加个玻璃罩

2010年4月20日 16:44
0 0

哦,重构了一下:
package org.corey.timer;

import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import javax.swing.JFrame;
import javax.swing.Timer;

public class TimerFrame extends JFrame implements KeyListener,MouseMotionListener,MouseWheelListener,ActionListener{

/**
*
*/
private static final long serialVersionUID = 1L;
private Timer timer;
private int delay;

public TimerFrame(int delay) throws HeadlessException {
this.delay=delay;
resetTimer();
this.addKeyListener(this);
this.addMouseMotionListener(this);
this.addMouseWheelListener(this);
}


protected void resetTimer(){
if(timer!=null){
timer.restart();
}else{
timer=new Timer(delay, this);
}
}


@Override
final public void mouseDragged(java.awt.event.MouseEvent e) {
resetTimer();
}


@Override
final public void mouseMoved(java.awt.event.MouseEvent e) {
resetTimer();
}


@Override
final public void mouseWheelMoved(MouseWheelEvent e) {
resetTimer();
}


@Override
final public void keyPressed(KeyEvent e) {
resetTimer();
}


@Override
final public void keyReleased(KeyEvent e) {
resetTimer();
}


@Override
final public void keyTyped(KeyEvent e) {
resetTimer();
}


@Override
final public void actionPerformed(ActionEvent e) {
timeOut();
}

public void timeOut(){

}
}



package org.corey.timer;

import java.awt.Dimension;
import java.awt.HeadlessException;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class App extends TimerFrame{

public App(int delay) throws HeadlessException {
super(delay);
this.setPreferredSize(new Dimension(300,300));
this.setVisible(true);
}



@Override
public void timeOut() {
JOptionPane.showMessageDialog(this, "退出!");
}



public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new App(5000);
}
});
}
}

2010年4月17日 12:41
0 0

package org.corey.timer;

import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;

public class TimerFrame extends JFrame implements KeyListener,MouseMotionListener,MouseWheelListener,ActionListener{

/**
*
*/
private static final long serialVersionUID = 1L;
private Timer timer;
private int delay;

public TimerFrame(int delay) throws HeadlessException {
this.delay=delay;
resetTimer();
this.addKeyListener(this);
this.addMouseMotionListener(this);
this.addMouseWheelListener(this);
}


protected void resetTimer(){
if(timer!=null){
timer.restart();
}else{
timer=new Timer(delay, this);
}
}


@Override
public void mouseDragged(java.awt.event.MouseEvent e) {
resetTimer();
}


@Override
public void mouseMoved(java.awt.event.MouseEvent e) {
resetTimer();
}


@Override
public void mouseWheelMoved(MouseWheelEvent e) {
resetTimer();
}


@Override
public void keyPressed(KeyEvent e) {
resetTimer();
}


@Override
public void keyReleased(KeyEvent e) {
resetTimer();
}


@Override
public void keyTyped(KeyEvent e) {
resetTimer();
}


@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, "退出!");
}

}


主界面扩展:
package org.corey.timer;

import java.awt.Dimension;
import java.awt.HeadlessException;

import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class App extends TimerFrame{

public App(int delay) throws HeadlessException {
super(delay);
this.setPreferredSize(new Dimension(300,300));
this.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new App(5000);
}
});
}
}


至于对于点解主界面子控件也能触发事件的解决方案,我对SWING不是特别熟悉,不知道是不是像JS等等一样存在冒泡或者说捕获这样的一个过程,如果是的话,则很好解决,如果不是,我觉得那就只能在子控件中将TimerFrame手动设置为监听器,或者
重载主界面的add方法,或者。。。。。只要能吧主控件在一个统一,集中的时候加入到子控件监听器里面去,单这个加入的代码一定要集中,避免后期你做改动;
如用主界面来做子控件工厂:
TimerFrame.createButton(){
   Button btn=new Button();
   btn.addActionListener(this);
   return btn;
}

AOP等等,应该都可以实现吧,期待牛人更好的解决方案

2010年4月17日 12:37
0 0

我没有用过Java开发界面,这个我帮不了你了。
哈哈,看看有没有其他朋友搞过这方面的东西。

2010年4月13日 21:20
0 0

这个问题你可以参考一下实际的ATM。

在用户不插入卡时,ATM一直显示欢迎画面(可能是广告等);
在用户插入卡后,这时ATM的画面就会发生变化。

对应你的程序,应该上也应该有这样的类似事件。比如用户按了某个按钮或输入某个快捷键,这时应该设置对应的timer了。当用户再进行某个操作,则取消之前的timer,并新设置一个timer。一直这样下去,直到用户正常操作结束,或timer超时。

用户操作正常结束或timer超时后,则ATM又重新进入欢迎画面。

2010年4月12日 19:21
0 0

在keyPressed、mousePressed方法内:timer.cancel();
keyReleased、mouseReleased方法内:新建一个同样的Timer,执行;

有一点需要说明:
上面对应的代码中的 timer 必须是同一个timer对象,否则得不到你要的结果。

2010年4月11日 20:32
0 0

这个问题实际可以通过这样的方法来实现。

在打开主界面后,就设置一个定时器(java.util.timer),该定时器的作用就是在1分钟弹出对话框“提示用户操作超时”;

java.util.Timer timer = new java.util.Timer();
timer.schedule(new java.util.TimerTask() {
	@Override
	public void run() {
		// 触发事件,弹出对话框“提示用户操作超时”
		// TODO 请自行实现
	}
}, 60000);


当用户进行了某种操作,则取消定时器,并重新设置定时器。
timer.cancel();

2010年4月10日 14:19

相关推荐

    Java线程超时监控

    首先,我们可以使用`java.util.concurrent`包中的`Future`和`ExecutorService`来实现线程超时。`ExecutorService`是一个接口,它提供了管理和控制线程池的能力,而`Future`则表示异步计算的结果。当我们提交一个任务...

    java通过线程控制程序执行超时(新)

    在Java编程中,控制程序执行超时是一项重要的任务,特别是在多线程环境下,我们可能需要确保某个任务不会无限制地运行下去,导致资源耗尽。本文将深入探讨如何使用Java的线程机制来实现程序执行的超时控制,同时也会...

    java通过线程控制程序执行超时

    在Java编程中,控制程序执行...总结来说,Java通过线程和定时器可以有效地控制程序执行超时,结合反射可以在运行时对目标对象进行灵活操作。在实际开发中,根据具体需求选择合适的方法,可以确保程序的稳定性和效率。

    Java中实现线程的超时中断方法实例

    Java中实现线程的超时中断方法实例 概述:在 Java 中实现线程的超时中断是非常重要的,特别是在熔断降级组件中。熔断降级组件需要在指定的超时时间内中断请求线程,以避免请求长时间阻塞系统资源。在这篇文章中,...

    Java线程状态流转图

    Java线程状态流转图知识点总结 Java线程状态流转图是一种用于描述Java线程生命周期中不同的状态和状态转换的图形表示方式。该图形展示了Java线程从创建到终止的整个生命周期,并详细介绍了每种状态的特点和转换...

    Java线程使用教程

    3. **线程优先级**:Java线程有10个优先级,通过`setPriority()`设置,但实际调度仍取决于操作系统。 4. **线程状态**:Java线程有新建、就绪、运行、阻塞和死亡五种状态,可以通过`getState()`获取。 三、线程池...

    JAVA线程学习(源代码)

    本资源"JAVA线程学习(源代码)"提供了关于Java线程的源代码示例,帮助我们深入理解和实践线程的使用。 首先,我们要理解Java中的线程模型。Java线程由`java.lang.Thread`类或`java.util.concurrent.Executor`框架来...

    java多线程经典案例

    Java提供了三种线程状态:新建(New)、运行(Runnable)、阻塞(Blocked)、等待(Waiting)、超时等待(Timed Waiting)和终止(Terminated)。阻塞状态通常发生在线程等待I/O操作完成、调用sleep()方法、等待锁...

    Java线程超时控制的实现.docx

    ### Java线程超时控制实现详解 #### 一、引言 在开发过程中,经常会遇到需要对线程执行时间进行限制的情况,例如与远程数据库的交互或网络数据的下载等耗时操作。为了提高程序的健壮性和用户体验,合理地控制这些...

    java多线程编程总结

    Java线程的状态包括新建 (`NEW`)、就绪 (`RUNNABLE`)、阻塞 (`BLOCKED`)、等待 (`WAITING`)、超时等待 (`TIMED_WAITING`) 和终止 (`TERMINATED`)。 #### 五、Java线程:线程的同步与锁 - **线程同步** 线程同步...

    Java线程培训资料

    ### Java线程培训资料知识点详解 #### 一、Java线程基本概念 1. **如何编写与启动线程** - **方式一:继承Thread类** ```java class MyThread extends Thread { @Override public void run() { // 业务逻辑 ...

    Java多线程编程核心技术_完整版_java_

    1. java.util.concurrent包下的工具类,如CountDownLatch、CyclicBarrier、Semaphore等,用于协调多个线程之间的操作。 以上内容只是《Java多线程编程核心技术》教程中的一部分核心知识点,实际学习中还需要结合...

    java线程安全测试

    Java线程安全是多线程编程中的一个关键概念,它涉及到多个线程访问共享资源时可能出现的问题。在Java中,线程安全问题通常与并发、内存模型和可见性有关。Java内存模型(JMM)定义了如何在多线程环境下共享数据的...

    线程超时死掉

    Future接口是Java线程Future模式的实 现,可以来进行异步计算。 Future模式可以这样来描述:我有一个任务,提交给了Future,Future替我完成这个任务。期间我自己可以去做任何想做的事情。一段时 间之后,我就便...

    java 线程池源代码

    3. `keepAliveTime`: 当线程数超过核心线程数时,空闲线程等待新任务的最长时间,超时会被终止。 4. `unit`: keepAliveTime的时间单位。 5. `workQueue`: 任务队列,用于存储待执行的任务。常见的有`...

    Java多线程编辑核心技术

    比如,CountDownLatch允许一个或多个线程等待其他线程完成操作,CyclicBarrier是一个同步点,使多个线程能够在屏障点上进行等待,直到所有线程都到达之后才能继续执行。Semaphore是一种基于计数信号量,用于限制访问...

    java 多线程并发实例

    Java的BlockingQueue接口(如ArrayBlockingQueue)非常适合实现这一模型,它提供了线程安全的数据插入和移除操作。 在实例中提到的"全部开始 全部停止 单个停止"可能涉及到线程的启动和控制,这可以通过控制线程的...

    Java多线程文档

    Java线程有三个优先级:MIN_PRIORITY(1)、NORM_PRIORITY(5)、MAX_PRIORITY(10),但优先级并不保证执行顺序,只是提供一种调度建议。 八、并发工具类 Java并发包(java.util.concurrent)提供了许多高级并发...

    Java多线程管理示例

    线程是操作系统分配CPU时间的基本单位,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和一部分堆内存。Java通过Thread类提供了对线程的封装和控制,我们可以通过创建Thread对象并重写其run()方法来实现并发...

    java经典多线程面试题

    - java.util.concurrent包中提供了一些线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList等,这些集合类能够在多线程环境下提供更安全且效率更高的数据操作。 11. Java中ReentrantLock和synchronized...

Global site tag (gtag.js) - Google Analytics