我不能让我的java代码等待例程完成另一个(相同的例程)

时间:2014-04-19 12:04:15

标签: java for-loop countdown

我想创建一个Java程序,允许我重复 - 5,4,3,2,1,0 FIRE - 我想要的次数。 我开始搜索如何创建倒计时,我使用计时器计划,所以我可以每1秒设置一次JTextFields文本(产生正常倒计时的效果)。但问题是,当我想重复时,免得说,这次倒计时的2倍,我的java代码同时开始倒计时,而不是等待第一个完成倒计时。我的主要目标是单击按钮并开始一定数量的倒计时。要生成的倒计时数在启用的JTextField中输入。

我将整个代码留在这里:

    import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;

import javax.swing.*;



public class Counter {

    public static class MyThread implements Runnable {
        private JTextField tx1;
        private JTextField tx2;
        CountDownLatch latch;

        int count;

        public MyThread (JTextField tx1,JTextField tx2,CountDownLatch latch) {
            this.tx1=tx1;
            this.tx2=tx2;
            this.latch = latch;
          }

        public void run() {
                 tx1.setText("");
                    tx2.setText("");
                    count=5;
                    Timer timer = new Timer();
                    timer.scheduleAtFixedRate(new TimerTask() {
                        int counter=0;
                          public void run() {
                             tx1.setText("");
                            tx1.setText(Integer.toString(count));
                            System.out.println("!");
                            count--;
                            counter++;
                            if (counter==6){
                                tx2.setText("FIRE");
                                this.cancel();
                            }
                          }
                        }, 1000,1000);
                        latch.countDown();

          } 
    }

public static void main(String[] args) {
    JFrame frame = new JFrame ("Counter");
    JPanel panel=new JPanel ();
    panel.setLayout(new GridLayout(3,2));
    JButton bt1=new JButton("Start");
    JButton bt2=new JButton("Reset");
    JLabel lb1=new JLabel ("Puffs");
    final JTextField tx1= new JTextField(5);
    final JTextField tx2= new JTextField(10);
    final JTextField tx3= new JTextField(5);
    tx1.setEnabled(false);
    tx2.setEnabled(false);
    panel.add(tx1);
    panel.add(tx2);
    panel.add(lb1);
    panel.add(tx3);
    panel.add(bt1);
    panel.add(bt2);
    frame.add(panel);

    CountDownLatch latch = new CountDownLatch(2);

    new Thread(new MyThread(tx1, tx2,latch)).start();
    new Thread(new MyThread(tx1, tx2,latch)).start();
    try {
        latch.await();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    bt1.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
//          int tr=Integer.parseInt(tx3.getText());

        }   
    });

    bt2.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {


            }

    });

    ////
    GraphicsConfiguration gc = frame.getGraphicsConfiguration();
    Rectangle bounds = gc.getBounds();

    Dimension size = frame.getPreferredSize();
    frame.setLocation((int) ((bounds.width / 2) - (size.getWidth() / 2)), 
            (int) ((bounds.height / 2) - (size.getHeight() / 2)));

    frame.setVisible(true);
    frame.pack();
     }
  }

抱歉格式错误和写错。 非常感谢你的帮助!

已编辑的代码

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;

import javax.swing.*;



public class Counter {

    public static class MyThread implements Runnable {
        private JTextField tx1;
        private JTextField tx2;

        int count;

        public MyThread (JTextField tx1,JTextField tx2) {
            this.tx1=tx1;
            this.tx2=tx2;
          }

        public void run() {
                 tx1.setText("");
                    tx2.setText("");
                    count=5;
                    Timer timer = new Timer();
                    timer.scheduleAtFixedRate(new TimerTask() {
                        int counter=0;
                          public void run() {
                             tx1.setText("");
                            tx1.setText(Integer.toString(count));
                            System.out.println("!");
                            count--;
                            counter++;
                            if (counter==6){
                                tx2.setText("FIRE");
                                this.cancel();
                            }
                          }
                        }, 1000,1000);

          } 
    }

public static void main(String[] args) {
    JFrame frame = new JFrame ("Counter");
    JPanel panel=new JPanel ();
    panel.setLayout(new GridLayout(3,2));
    JButton bt1=new JButton("Start");
    JButton bt2=new JButton("Reset");
    JLabel lb1=new JLabel ("Puffs");
    final JTextField tx1= new JTextField(5);
    final JTextField tx2= new JTextField(10);
    final JTextField tx3= new JTextField(5);
    tx1.setEnabled(false);
    tx2.setEnabled(false);
    panel.add(tx1);
    panel.add(tx2);
    panel.add(lb1);
    panel.add(tx3);
    panel.add(bt1);
    panel.add(bt2);
    frame.add(panel);

    bt1.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
//          int tr=Integer.parseInt(tx3.getText());
            Thread t1 = new Thread(new MyThread(tx1, tx2));
            Thread t2 = new Thread(new MyThread(tx1, tx2));
            t1.start();
            try {
                t1.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            t2.start();
            try {
                t2.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }   
    });

    bt2.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            }

    });

    ////
    GraphicsConfiguration gc = frame.getGraphicsConfiguration();
    Rectangle bounds = gc.getBounds();
    Dimension size = frame.getPreferredSize();
    frame.setLocation((int) ((bounds.width / 2) - (size.getWidth() / 2)), 
            (int) ((bounds.height / 2) - (size.getHeight() / 2)));
    frame.setVisible(true);
    frame.pack();
     }
  }

3 个答案:

答案 0 :(得分:0)

是的,这将同时启动Timer。使用此代码。

 CountDownLatch latch = new CountDownLatch(2);

    new Thread(new MyThread(tx1, tx2,latch)).start();
    new Thread(new MyThread(tx1, tx2,latch)).start();
    try {
        latch.await();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

但是你可以让第二个计时器在第一个计时器结束后执行。 在第一个计时器结束后把它放好。

new Thread(new MyThread(tx1, tx2,latch)).start();

答案 1 :(得分:0)

如果你在不同的线程中启动计时器,它们自然会被同时执行:这就是线程的目的。

如果要同步它们,例如,在前一个线程完成时启动一个线程,则可以使用join()函数,该函数将“暂停”代码直到线程完成。

Thread t1 = new Thread(new MyThread(tx1, tx2, latch));
Thread t2 = new Thread(new MyThread(tx1, tx2, latch));
t1.start();
t1.join();
t2.start();
t2.join();
// ...

因此,t2仅在t1结束后才开始 你可以将它应用于for循环,在循环中你跟踪前一个线程,并在oldThread.join()之后开始下一个。

希望它可以帮到你!

答案 2 :(得分:0)

嘿,我终于找到了代码中的缺陷。您发布的第一个代码(不是已编辑的代码)是正确的代码,也是使用CountDownLatch(用于同步)的正确方法。 我刚刚更改了您的MyThread班级run()方法。只是看看它。

public static class MyThread implements Runnable {
        private JTextField tx1;
        private JTextField tx2;
        CountDownLatch latch;

        int count;

        public MyThread (JTextField tx1,JTextField tx2,CountDownLatch latch) {
            this.tx1=tx1;
            this.tx2=tx2;
            this.latch = latch;
          }

        public void run() {
                 tx1.setText("");
                    tx2.setText("");
                    count=5;
                    Timer timer = new Timer();
                    timer.scheduleAtFixedRate(new TimerTask() {
                        int counter=0;
                          public void run() {
                             tx1.setText("");
                            tx1.setText(Integer.toString(count));
                            System.out.println("!");
                            count--;
                            counter++;
                            if (counter==6){
                                tx2.setText("FIRE");
 latch.countDown();
                                this.cancel();
                            }
                          }
                        }, 1000,1000);
                        //latch.countDown();Detailed Explaination is below.

          } 
    }

latch.countDown()在第一次Thread开始时直接执行。因此,您希望将其置于if条件中。因此第二个Thread将等待第一个Thread latch.countDown()即将完成。 CountDownLatch方法就像一个网关开启者。当调用此函数时,Thread中的倒计时将递减1.因此CountDownLatch中的下一个{{1}}将会被执行。 希望这会对你有所帮助。