尝试使用线程时程序锁定

时间:2013-04-05 17:24:39

标签: java multithreading

这是我在这里的第一篇文章,所以希望它一切都好。

我在netbeans。我用按钮等制作了一个窗口。

我有一个名为SimpleThread的类,如下所示:

public class SimpleThread extends Thread {

public SimpleThread()
{

}

@Override
public void run()
{

}

我有不同类型的子类线程来扩展simplethread(TimerThread,MouseGrabThread)。

public class MouseGrabThread extends SimpleThread{

private Point pt;
private JTextField x, y;

public MouseGrabThread(JTextField x, JTextField y)
{
    super();
    this.x = x; 
    this.y = y;
}

@Override
public void run()
{
    while(this.isAlive())
    {
        int[] xyVal = new int[2];
        xyVal = getCoords();
        x.setText("" + xyVal[0]);
        y.setText("" + xyVal[1]);
    }
}

public int[] getCoords()
{
    Point pt = MouseInfo.getPointerInfo().getLocation();

    int[] retArr = new int[2];
    retArr[0] = (int)pt.getX();
    retArr[1] = (int)pt.getY();

    return retArr;

}



public class TimerThread extends SimpleThread {

private JTextArea label;
private int time;

public TimerThread(JTextArea label, int time)
{
    super();
    this.label = label;
    this.time = time;
}

@Override
public void run()
{
    int counter = time;
    while(counter != -1)
    {

        label.setText("You have: " + counter + " seconds until the timer ends!\n");
        counter--;
        try {
            this.sleep(1000);
        } catch (InterruptedException ex) {
            System.out.println("Thread Interrupted");
        }

    }
    stop();
}

在我的UI窗口类中,我有这个:

private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {                                      
   SimpleThread timer = new TimerThread(jTextArea1, 10); //This counts down from 10 seconds and updates a status text box each second
   SimpleThread mouseGrab = new MouseGrabThread(jTextField1, jTextField2); //This grabs mouse coords and updates two boxes in the UI.
   timer.start();
   if(timer.isAlive())
   {
      mouseGrab.start();
   }
   while(timer.isAlive())//######
   {
       if(!mouseGrab.isAlive())
       {
           mouseGrab.start();
       }
   }
}           

当我按下按钮时,程序会冻结10秒钟。

我想我标记的行(// #####)是导致UI在定时器持续时间内冻结的行,导致它在主线程中运行。我不确定如何纠正这个问题。

请原谅我缺乏编程知识,我现在正在自己进入线程,而我正在大学学习数据结构非常简单的课程。如果可能的话,你能尽可能地“愚蠢”回答吗?

另外,我知道我这样做很糟糕,但是我调用了stop()函数,即使它不好看(不要用它来拍我,我不知道怎么做!)如果有人可以为我解答如何做得很好,太棒了!

1 个答案:

答案 0 :(得分:1)

您可能想要的是在倒计时结束时结束mouseGrab

private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {                                      
   SimpleThread timer = new TimerThread(jTextArea1, 10); //This counts down from 10 seconds and updates a status text box each second
   SimpleThread mouseGrab = new MouseGrabThread(jTextField1, jTextField2); //This grabs mouse coords and updates two boxes in the UI.

   mouseGrab.start();
   timer.start();

   // Wait until countdown finishes
   while(timer.isAlive()) {}

   mouseGrab.stop();
}

在您粘贴的代码中,当mouseGrab正在运行时,您一直在启动timer。您可能更愿意在计时器开启时​​让鼠标抓取。

修改:确实,stop()已弃用,您确实应该在boolean running中使用TimerThread属性并包含其run()的内容某些

中的方法
while (running) {
    /* stuff */
}

然后用一些setter从外部“停止”这个线程。那么正确的答案将是例如:

   mouseGrab.start();
   timer.start();

   // Wait until countdown finishes
   while(timer.isAlive()) {}

   mouseGrab.setRunning(false);
}

Edit2 :这最终似乎是你想要的:

private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {                                      
   SimpleThread mouseGrab = new MouseGrabThread(jTextField1, jTextField2); //This grabs mouse coords and updates two boxes in the UI.
   SimpleThread timer = new TimerThread(mouseGrab, jTextArea1, 10); //This counts down from 10 seconds and updates a status text box each second

   mouseGrab.start();
   timer.start();
}

使用:

public class MouseGrabThread extends SimpleThread {

    private Point pt;
    private JTextField x, y;
    private boolean running;

    public MouseGrabThread(JTextField x, JTextField y) {
        super();
        this.x = x; 
        this.y = y;
    }

    @Override
    public void run() {
        running = true;
        while(running) {
            int[] xyVal = new int[2];
            xyVal = getCoords();
            x.setText("" + xyVal[0]);
            y.setText("" + xyVal[1]);
        }
    }

    public int[] getCoords() {
        Point pt = MouseInfo.getPointerInfo().getLocation();

        int[] retArr = new int[2];
        retArr[0] = (int)pt.getX();
        retArr[1] = (int)pt.getY();

        return retArr;

    }

    public void break() {
        this.running = false;
    }
}


// ------------- //


public class TimerThread extends SimpleThread {

    private MouseGrabThread mouseGrab;
    private JTextArea label;
    private int time;

    public TimerThread(MouseGrabThread mouseGrab, JTextArea label, int time)
    {
        super();
        this.label = label;
        this.time = time;
        this.mouseGrab = mouseGrab;
    }

    @Override
    public void run()
    {
        int counter = time;
        while(counter != -1)
        {
            label.setText("You have: " + counter + " seconds until the timer ends!\n");
            counter--;
            try {
                this.sleep(1000);
            } catch (InterruptedException ex) {
                System.out.println("Thread Interrupted");
            }

        }

        mouseGrab.break();
    }
}