如何在线程循环中进行阶段化?

时间:2013-11-24 12:52:13

标签: java multithreading swing

我有线程类,它将lable值从0增加到n。线程代码:

public class 

    SimpleThread implements Runnable {

            Thread t;
            volatile boolean stop = true;
        int n;
        JLabel label;
        String name;

        SimpleThread(String name) {
            this.name = name;
            t = new Thread(this, "settingThread");
            t.start();
        }


        public void run() {
            while (true) {

                while (stop) {


                }

                System.out.println(name + " stop:" + stop);
                for (int i = 0; i < n; i++) {
                    label.setText(String.valueOf(i));
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }
                }
                stop = true;

            }
        }

        public void start(int n, JLabel label) {
            stop = false;
            this.n = n;
            this.label = label;
        }
    }

线程必须有效,直到stop值不是true。此外,我有两个不同参数的线程对象st1st2

st1.start(10, timeLabel1);
st2.start(5, timeLabel2); 

因此,第一个线程应该将timeLabel1从0增加到10和st2 - 从0增加到5.现在问题。如何让我的程序等到线程在循环中通过阶段?我的意思是这样的:

 public void run() {
            while (true) {

                while (stop) {


                }

                System.out.println(name + " stop:" + stop);
                for (int i = 0; i < n; i++) {
                    label.setText(String.valueOf(i));
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }
                }
                stop = true;
                //stage

            }
        }

然后:

st1.start(10, timeLabel1);
        st2.start(5, timeLabel2);
        //wait until both stages aren't done
        System.out.println("yep");

代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * Created with IntelliJ IDEA.
 * User: Администратор
 * Date: 22.11.13
 * Time: 21:17
 * To change this template use File | Settings | File Templates.
 */
public class StackOverflow implements ActionListener {
    JButton button = new JButton("Button");

    SimpleThread st1 = new SimpleThread("1st"), st2 = new SimpleThread("2nd");

    JLabel timeLabel1 = new JLabel("0"), timeLabel2 = new JLabel("0");


    StackOverflow() {


        JFrame jfrm = new JFrame("Strategy fighting");
        jfrm.setLayout(new FlowLayout());
        jfrm.setSize(300, 150);

        jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        button.addActionListener(this);
        jfrm.add(button);
        jfrm.add(timeLabel1);
        jfrm.add(timeLabel2);


        jfrm.setVisible(true);
    }


    public class SimpleThread implements Runnable {

        Thread t;
        volatile boolean stop = true;
        int n;
        JLabel label;
        String name;

        SimpleThread(String name) {
            this.name = name;
            t = new Thread(this, "settingThread");
            t.start();
        }


        public void run() {
            while (true) {

                while (stop) {


                }

                System.out.println(name + " stop:" + stop);
                for (int i = 0; i < n; i++) {
                    label.setText(String.valueOf(i));
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }
                }
                stop = true;


            }
        }

        public void start(int n, JLabel label) {
            stop = false;
            this.n = n;
            this.label = label;
        }
    }


    public void actionPerformed(ActionEvent e) {

        st1.start(10, timeLabel1);
        st2.start(5, timeLabel2);

        System.out.println("yep");

    }

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

            public void run() {
                new StackOverflow();
            }
        });
    }
}

1 个答案:

答案 0 :(得分:0)

你的问题已经有了答案:Phaser课程。 ;)

这样的事情可以解决问题:

static final Phaser phaser = new Phaser(NUM_THREADS + 1); // +1 for the main thread

在你的主题中:

run() {
  // do stage 1
  phaser.arriveAndAwaitAdvance(); // wait until everyone is done with stage 1
  // do stage 2
}

在你的主要:

startThreads(NUM_THREADS);
phaser.arriveAndAwaitAdvance(); // wait until stage 1 is done
// ... do something else