使用同步对象隔离从多个线程执行的功能

时间:2016-03-18 15:43:11

标签: java multithreading

尝试使用同步对象将函数actionPerformed()与几个线程的执行隔离开来。不幸的是,即使另一个函数已进入synchronized (reqSync),这也没有帮助,并且执行了函数。为什么?如何解决这个问题?

public class MnemonicEx1 extends JFrame
{

    public JeasiHandler jh = null;
    private Log log = Log.getLog();
    public static Object reqSync = new Object();

    public MnemonicEx1()
    {

        initUI();
    }

    private void initUI()
    {

        JButton btnAuth = new JButton("1");
        btnAuth.setMnemonic(KeyEvent.VK_B);

        createLayout(btnAuth);

        setTitle("****");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        btnAuth.addActionListener(new ActionListener()
        {

            // @Override
            public void actionPerformed(ActionEvent e)
            {
                synchronized (reqSync)
                {
                    new Thread()
                    {

                        public void run()
                        {
                            System.out.println("starting");
                            for (int i = 0; i < 1000; i++)
                            {
                                try
                                {
                                    Thread.sleep(100);
                                    System.out.println(Integer.toString(i));
                                } catch (InterruptedException ex)
                                {
                                    ex.printStackTrace();
                                }
                            }

                            System.out.println("finishing");
                        }

                    }.start();

                }
            }

        });

    }

    private void createLayout(JComponent authButn)
    {

        Container pane = getContentPane();
        GroupLayout gl = new GroupLayout(pane);
        pane.setLayout(gl);

        gl.setAutoCreateContainerGaps(true);

        int i = 0;
        gl.setHorizontalGroup(
                gl.createSequentialGroup()
                .addComponent(authButn)
        );

        gl.setVerticalGroup(gl.createParallelGroup()
                .addComponent(authButn)
        );

        pack();
    }

    public static void main(String[] args)
    {

        SwingUtilities.invokeLater(new Runnable()
        {

            public void run()
            {
                MnemonicEx1 ex = new MnemonicEx1();
                ex.setVisible(true);
            }
        });

        SwingUtilities.invokeLater(new Runnable()
        {

            public void run()
            {
                MnemonicEx1 ex = new MnemonicEx1();
                ex.setVisible(true);
            }
        });

    }
}

2 个答案:

答案 0 :(得分:2)

就您当前的尝试而言,同步需要在线程内部。您目前正在阻止的是同时启动多个线程;一旦开始,你就不能同时停止它们。

new Thread() {
  public void run() {
    synchronized (reqSync) {
      // ...
    }
  }
}

请注意,您可能实际上想要做一些 little 与此不同的事情 - 这并不会阻止用户多次按下按钮,并排队等待很多线程一次运行一次。

相反,您可以进行此操作,以便在线程完成之前放弃对块的后续单击:

// As a member variable instead of reqSync:
static final Semaphore MUTEX = new Semaphore(1);

// In the body:
public void actionPerformed(ActionEvent e) {
  if (MUTEX.tryAcquire()) {
    new Thread() {
      @Override public void run() {
        try {
          // ...
        } finally {
          MUTEX.release();
        }
      }
    }.start();
  }
}

答案 1 :(得分:0)

鉴于此时您想使用全局同步,在这里使用线程没有意义。我建议将此代码简化为:

.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
    xlBetween, Formula1:="=indirect($C$8)"

public void actionPerformed(ActionEvent e){

// @Override

}