- 论坛徽章:
- 0
|
请教:线程监视器状态异常
谢谢你提供的参考!!
这是之前发现的线程控制变量b2的一些想法:
- /*
- * 创建日期 2004-11-25
- *
- * TODO 要更改此生成的文件的模板,请转至
- * 窗口 - 首选项 - Java - 代码样式 - 代码模板
- */
- /**
- * @author ttl_web
- *
- * TODO 要更改此生成的类型注释的模板,请转至
- * 窗口 - 首选项 - Java - 代码样式 - 代码模板
- */
- import java.awt.*;
- import java.awt.event.*;
- //import java.applet.*;
- import javax.swing.*;
- import java.io.*;
- //采用线程为计时器,实现Runnable接口run()
- public class TestArea extends JPanel implements Runnable {
- Box bx1,bx2,bx3;
-
- JLabel jl1,jl2,jl3,jl4;
- //Choice ch1;
- JComboBox jcb1;
- JTextArea jta1,jta2;
- JScrollPane jsp1,jsp2;
- JButton jb1,jb2,jb3,jb4;
- JTextField jtf1;
- ButtonGroup bg1;
- JRadioButton[] jrb1;
-
- JPanel jp1,jp2;
-
- //计时器线程
- Thread t1;
- //计时器开关,暂停开关
- boolean b1,b2;
- //本次考试时间
- long l1;
- //含有试题和结果信息
- ReadTestQuestion rtq1;
-
- public TestArea() {
- //使用盒子来布局框架;2个水平盒子和1个垂直盒子
- bx1=Box.createVerticalBox();
- bx2=Box.createVerticalBox();
- bx3=Box.createHorizontalBox();
-
- jl1=new JLabel("参加考试 提高水平");
- jl1.setFont(new Font("幼圆",Font.BOLD,18));
-
- jl2=new JLabel("选择试题文件");
- jl2.setFont(new Font("幼圆",Font.PLAIN,16));
- jl3=new JLabel("剩余时间");
- jl3.setFont(new Font("幼圆",Font.PLAIN,16));
- jl4=new JLabel("试题显示");
- jl4.setFont(new Font("幼圆",Font.PLAIN,16));
-
- //文件读写:
- //1.文件目录根据System属性;
- //2.后缀根据实现了文件过滤的FileLastName确定;
- //3.同目录下的多个文件名由文件类根据后缀动态加载到文件名字符串数组实现;
- String s1=System.getProperty("user.dir");
- File f1=new File(s1);
- FileLastName fln1=new FileLastName("txt");
- String[] s2=f1.list(fln1);
-
- //加载到JComboBox
- jcb1=new JComboBox();
- jcb1.setFont(new Font("幼圆",Font.PLAIN,16));
- jcb1.addItem("单击选择试题文件");
- for(int i=0;i<s2.length;i++) {
- jcb1.addItem(s2[i]);
- }
-
- //监听jcb1下拉列表的状态变化
- jcb1.addItemListener(new jcb1ItemListener(this));
-
- jta1=new JTextArea(8,4);
- jta2=new JTextArea(12,6);
- jta1.setLineWrap(true);
- jta2.setLineWrap(true);
- jta1.setWrapStyleWord(true);
- jta2.setWrapStyleWord(true);
-
- jsp1=new JScrollPane(jta1);
- jsp2=new JScrollPane(jta2);
-
- jb1=new JButton("查看分数");
- jb1.setFont(new Font("幼圆",Font.PLAIN,16));
- jb1.addActionListener(new thisActionListener(this));
- jb1.setToolTipText("可以看到你的测试结果");
- jb2=new JButton("暂停或继续计时");
- jb2.setFont(new Font("幼圆",Font.PLAIN,16));
- jb2.addActionListener(new thisActionListener(this));
- jb2.setToolTipText("你可以暂时休息一下");
- jb3=new JButton("提交答案");
- jb3.setFont(new Font("幼圆",Font.PLAIN,16));
- jb3.addActionListener(new thisActionListener(this));
- jb3.setToolTipText("提交后点击查分按钮");
- jb4=new JButton("读取首题");
- jb4.setFont(new Font("幼圆",Font.PLAIN,16));
- jb4.addActionListener(new thisActionListener(this));
- jb4.setToolTipText("看看后面的题目");
-
- jtf1=new JTextField(20);
- jtf1.setEditable(false);
-
- bg1=new ButtonGroup();
- jrb1=new JRadioButton[4];
- String[] jrb1S={"A","B","C","D"};
- for(int i=0;i<jrb1S.length;i++) {
- jrb1[i]=new JRadioButton(jrb1S[i]);
- bg1.add(jrb1[i]);
- }
-
- jp1=new JPanel();
- jp2=new JPanel();
-
- jp1.add(jb1);
- jp1.add(jb2);
- bx1.add(jl2);
- bx1.add(jcb1);
- bx1.add(jsp1);
- bx1.add(jp1);
- bx1.add(jl3);
- bx1.add(jtf1);
-
- for(int i=0;i<jrb1S.length;i++) {
- jp2.add(jrb1[i]);
- }
- jp2.add(jb3);
- jp2.add(jb4);
-
- bx2.add(jl4);
- bx2.add(jsp2);
- bx2.add(jp2);
-
- bx3.add(bx1);
- bx3.add(bx2);
-
- setLayout(new BorderLayout());
- add(jl1,BorderLayout.NORTH);
- add(bx3,BorderLayout.CENTER);
-
- //计时器初始化,默认为null,即为没有计时器
- //计时器暂停开关,初始化为关闭
- b1=false;
- b2=false;
- t1=new Thread(this);
- rtq1=new ReadTestQuestion();
- }
-
- public synchronized void run() {
- while(true) {
- if(l1<=0) {
- jb3.setEnabled(false);
- jb4.setEnabled(true);
- b1=true;
- t1.interrupt();
- jtf1.setText("时间用完 测试结束");
- }
- else if(rtq1.getFinsh()) {
- b1=true;
- jtf1.setText("测试结果:"+rtq1.getSorce()+" 考试剩余时间:"+l1);
- }
- else {
- long TS=l1/1000;
- long H=TS/3600;TS=TS%3600;
- long M=TS/60;TS=TS%60;
- long S=TS;
- jtf1.setText("还有 "+H+" 时 "+M+" 分 "+S+" 秒 ");
-
- //时间减少
- l1=l1-1000;
- }
-
- try {
- Thread.sleep(1000);
- } catch(InterruptedException ie) {
- if (b1==true) {
- return ;
- }
- }
-
- while(b2==true) {
- try {
- wait();
- } catch(InterruptedException ie) {
- if(b2==false) {
- notifyAll();
- }
- }
- }
- }
- }
-
- class jcb1ItemListener implements ItemListener {
- TestArea ta1;
-
- public jcb1ItemListener(TestArea ta1) {
- this.ta1=ta1;
- }
- public void itemStateChanged(ItemEvent ie) {
- jtf1.setText("");
- jta1.setText("");
- jta2.setText("");
- for(int i=0;i<4;i++) {
- jrb1[i].setSelected(false);
- }
- jb3.setEnabled(false);
- jb4.setEnabled(true);
- //获取选择的试题文件
- String s1=jcb1.getSelectedItem().toString().trim();
-
- if(s1.equals("单击选择试题文件")) {
- jl1.setText("重新选择");
- return ;
- }
- else {
- jl1.setText("试题 "+s1+" 认真作答 祝福通关");
-
- //设置要读取的文件名根据选择了的文件名
- rtq1.setFilename(s1);
- //初始化尚未完成考试
- rtq1.setFinsh(false);
- //获取本次考试的时间,根据试题文件的规定
- l1=rtq1.getTestTime();
-
- //关闭已经开启的计时器,同时把计时器置为中断状态
- if(t1.isAlive()) {
- t1.interrupt();
- b1=true;
- }
-
- //实例化计时器线程
- t1=new Thread(ta1);
- }
- }
- }
-
- class thisActionListener implements ActionListener {
- TestArea ta1;
- public thisActionListener(TestArea ta1) {
- this.ta1=ta1;
- }
- public void actionPerformed(ActionEvent ae) {
-
- //读取试题
- if(ae.getSource()==jb4) {
- String s1=rtq1.getTestContent();
- for(int i=0;i<4;i++) {
- jrb1[i].setSelected(false);
- }
- try {
- t1.start();
- }catch(Exception e) {
- }
-
- jta1.setText("");
- jta2.setText(s1);
- jb3.setEnabled(true);
- jb4.setEnabled(false);
- }
- //查看分数
- if(ae.getSource()==jb1) {
- int i1=rtq1.getSorce();
- String s1=rtq1.getMessage();
- jta1.setText("你的测试得分:"+i1+"\n\n测试情况:\n"+s1);
- }
-
- //暂停或继续计时
- if(ae.getSource()==jb2) {
- if(b2==false) {
- b2=true;
- jb2.setText("继续计时");
- //t1.interrupt();
- }
- else {
- jb2.setText("暂停计时");
- //if (b2==true){
- // t1.notifyAll();
- //}
- b2=false;
- t1.interrupt();
- }
- }
-
- //提交答案
- if(ae.getSource()==jb3) {
- jb3.setEnabled(false);
- jb4.setEnabled(true);
-
- String s1="?";
- for(int i=0;i<4;i++) {
- if(jrb1[i].isSelected()) {
- s1=jrb1[i].getText();
- break;
- }
- }
- jb4.setText("读取下题");
- rtq1.setSelect(s1);
- }
- }
- }
- }
- //文件后缀过滤
- class FileLastName implements FilenameFilter {
- String s1;
- public FileLastName(String s1) {
- this.s1="."+s1;
- }
- //这里f1是目录;s2是文件名
- public boolean accept(File f1,String s2) {
- return s2.endsWith(s1);
- }
- }
复制代码
采用局部变量来控制线程的运行和退出
b1,b2默认是false:关闭计时器,暂停开关没有打开
run()中时间用尽时,中断线程cT.interrupt(),结束run();
如果还有时间time>;=1,每次while减少1000毫秒,同时捕获休眠异常,检查b1,b2(计时器关闭时退出;暂停打开时,等待唤醒,捕获等待异常);
这里的b2 来自TextArea对象中的局部变量 |
|