尝试使用同步对象将函数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);
}
});
}
}
答案 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
}