-
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个答案 按时间排序 按投票排序
-
我觉得可以写一个线程类,设置属性时间time=60,在run方法里:
while(time != 0){
Thread.sleep(1000);
time --;
}
----其他退出或则提示操作。
每次有按键或则输入操作的时候 调用setTime(60);
不知道这样行不呢?2010年4月21日 15:08
-
哦,重构了一下:
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
-
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
-
这个问题你可以参考一下实际的ATM。
在用户不插入卡时,ATM一直显示欢迎画面(可能是广告等);
在用户插入卡后,这时ATM的画面就会发生变化。
对应你的程序,应该上也应该有这样的类似事件。比如用户按了某个按钮或输入某个快捷键,这时应该设置对应的timer了。当用户再进行某个操作,则取消之前的timer,并新设置一个timer。一直这样下去,直到用户正常操作结束,或timer超时。
用户操作正常结束或timer超时后,则ATM又重新进入欢迎画面。2010年4月12日 19:21
-
在keyPressed、mousePressed方法内:timer.cancel();
keyReleased、mouseReleased方法内:新建一个同样的Timer,执行;
有一点需要说明:
上面对应的代码中的 timer 必须是同一个timer对象,否则得不到你要的结果。2010年4月11日 20:32
-
这个问题实际可以通过这样的方法来实现。
在打开主界面后,就设置一个定时器(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.util.concurrent`包中的`Future`和`ExecutorService`来实现线程超时。`ExecutorService`是一个接口,它提供了管理和控制线程池的能力,而`Future`则表示异步计算的结果。当我们提交一个任务...
在Java编程中,控制程序执行超时是一项重要的任务,特别是在多线程环境下,我们可能需要确保某个任务不会无限制地运行下去,导致资源耗尽。本文将深入探讨如何使用Java的线程机制来实现程序执行的超时控制,同时也会...
在Java编程中,控制程序执行...总结来说,Java通过线程和定时器可以有效地控制程序执行超时,结合反射可以在运行时对目标对象进行灵活操作。在实际开发中,根据具体需求选择合适的方法,可以确保程序的稳定性和效率。
Java中实现线程的超时中断方法实例 概述:在 Java 中实现线程的超时中断是非常重要的,特别是在熔断降级组件中。熔断降级组件需要在指定的超时时间内中断请求线程,以避免请求长时间阻塞系统资源。在这篇文章中,...
Java线程状态流转图知识点总结 Java线程状态流转图是一种用于描述Java线程生命周期中不同的状态和状态转换的图形表示方式。该图形展示了Java线程从创建到终止的整个生命周期,并详细介绍了每种状态的特点和转换...
3. **线程优先级**:Java线程有10个优先级,通过`setPriority()`设置,但实际调度仍取决于操作系统。 4. **线程状态**:Java线程有新建、就绪、运行、阻塞和死亡五种状态,可以通过`getState()`获取。 三、线程池...
本资源"JAVA线程学习(源代码)"提供了关于Java线程的源代码示例,帮助我们深入理解和实践线程的使用。 首先,我们要理解Java中的线程模型。Java线程由`java.lang.Thread`类或`java.util.concurrent.Executor`框架来...
Java提供了三种线程状态:新建(New)、运行(Runnable)、阻塞(Blocked)、等待(Waiting)、超时等待(Timed Waiting)和终止(Terminated)。阻塞状态通常发生在线程等待I/O操作完成、调用sleep()方法、等待锁...
### Java线程超时控制实现详解 #### 一、引言 在开发过程中,经常会遇到需要对线程执行时间进行限制的情况,例如与远程数据库的交互或网络数据的下载等耗时操作。为了提高程序的健壮性和用户体验,合理地控制这些...
Java线程的状态包括新建 (`NEW`)、就绪 (`RUNNABLE`)、阻塞 (`BLOCKED`)、等待 (`WAITING`)、超时等待 (`TIMED_WAITING`) 和终止 (`TERMINATED`)。 #### 五、Java线程:线程的同步与锁 - **线程同步** 线程同步...
### Java线程培训资料知识点详解 #### 一、Java线程基本概念 1. **如何编写与启动线程** - **方式一:继承Thread类** ```java class MyThread extends Thread { @Override public void run() { // 业务逻辑 ...
1. java.util.concurrent包下的工具类,如CountDownLatch、CyclicBarrier、Semaphore等,用于协调多个线程之间的操作。 以上内容只是《Java多线程编程核心技术》教程中的一部分核心知识点,实际学习中还需要结合...
Java线程安全是多线程编程中的一个关键概念,它涉及到多个线程访问共享资源时可能出现的问题。在Java中,线程安全问题通常与并发、内存模型和可见性有关。Java内存模型(JMM)定义了如何在多线程环境下共享数据的...
Future接口是Java线程Future模式的实 现,可以来进行异步计算。 Future模式可以这样来描述:我有一个任务,提交给了Future,Future替我完成这个任务。期间我自己可以去做任何想做的事情。一段时 间之后,我就便...
3. `keepAliveTime`: 当线程数超过核心线程数时,空闲线程等待新任务的最长时间,超时会被终止。 4. `unit`: keepAliveTime的时间单位。 5. `workQueue`: 任务队列,用于存储待执行的任务。常见的有`...
比如,CountDownLatch允许一个或多个线程等待其他线程完成操作,CyclicBarrier是一个同步点,使多个线程能够在屏障点上进行等待,直到所有线程都到达之后才能继续执行。Semaphore是一种基于计数信号量,用于限制访问...
Java的BlockingQueue接口(如ArrayBlockingQueue)非常适合实现这一模型,它提供了线程安全的数据插入和移除操作。 在实例中提到的"全部开始 全部停止 单个停止"可能涉及到线程的启动和控制,这可以通过控制线程的...
Java线程有三个优先级:MIN_PRIORITY(1)、NORM_PRIORITY(5)、MAX_PRIORITY(10),但优先级并不保证执行顺序,只是提供一种调度建议。 八、并发工具类 Java并发包(java.util.concurrent)提供了许多高级并发...
线程是操作系统分配CPU时间的基本单位,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和一部分堆内存。Java通过Thread类提供了对线程的封装和控制,我们可以通过创建Thread对象并重写其run()方法来实现并发...
- java.util.concurrent包中提供了一些线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList等,这些集合类能够在多线程环境下提供更安全且效率更高的数据操作。 11. Java中ReentrantLock和synchronized...