函数内部弹出一消息框,synchronized关键字不起作用了? 设一个类的A函数是synchronized的,在A内部弹出一消息框,使A的执行时间很长,此时发现在消息框未退出时,另一个synchronized函数B可被顺利进入(对同一个对象)。synchronized不起作用了? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 没有代码很难判断是哪里的问题我blog中有一个《Java线程之线程同步》,你可以参考下:http://blog.csdn.net/mq612/archive/2007/03/04/1520583.aspx synchronized不太可能不起作用的,一定是你的程序设计欠妥 我写一个测试程序:import java.awt.*;import java.awt.event.*;import javax.swing.*;//import javax.swing.JOptionPane;public class TestSyn extends JFrame{ private ActionListener alButton; private JButton jbB1,jbB2; private Timer mainTimer; public TestSyn() { setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setTitle("TestSyn"); alButton=new ButtonListener(this); jbB1=new JButton("Button1"); jbB1.addActionListener(alButton); jbB2=new JButton("Button2"); jbB2.addActionListener(alButton); Container cp=getContentPane(); GridBagLayout gbl=new GridBagLayout(); cp.setLayout(gbl); GridBagConstraints gbc=new GridBagConstraints(); gbc.fill=GridBagConstraints.BOTH; gbc.weightx=1.0; gbc.weighty=0.0; gbc.gridwidth=1; gbc.insets=new Insets(5,2,5,2); cp.add(jbB1); cp.add(jbB2); setSize(320,320); setVisible(true); mainTimer=new Timer(3000,null); mainTimer.addActionListener(alButton); } public static void main(String args[]) { TestSyn mainFrame=new TestSyn(); } public JButton getButton1() { return jbB1; } public JButton getButton2() { return jbB2; } public Timer getTimer() { return mainTimer; } synchronized public void doButton1() { mainTimer.start(); JOptionPane.showConfirmDialog (this,"In doButton1","ABC", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE); System.out.println("in doButton1()!"); } public void doButton2() { System.out.println("in doButton2()!"); } synchronized public void doTimer() { System.out.println("in doTimer()!"); mainTimer.stop(); }}class ButtonListener implements ActionListener{ private TestSyn testsyn; public ButtonListener(TestSyn ts) { testsyn=ts; } public void actionPerformed(ActionEvent e) { Object eventObject=e.getSource(); if(eventObject==testsyn.getButton1()) testsyn.doButton1(); else if(eventObject==testsyn.getButton2()) testsyn.doButton2(); else if(eventObject==testsyn.getTimer()) testsyn.doTimer(); }}在JBuilder下运行时,发现按下button1后,显示消息框,在不退出消息框的情况下,3秒后依然会显示in doTimer()!信息,这不是synchronized不起作用了吗?还是定时器有什么“特权”? synchronized表示该方法或者该代码段是同步执行的, 也就是A方法是synchronized的话, 同一个时间点, 只可能有一个A方法在被执行. 而同一个类的B方法,不管是不是synchronized或者A是不是在执行都可以被执行.你说的问题, 我想应该是JOptionPane显示出来的对话框不是Modal模式的, 因此后台的Timer仍然在反复执行. 如果你换一个Modal方式的JDialog跳出来, 试试看, 在Dialog还没有关掉的情况下是不是doTimer方法仍然被执行呢? 楼上的看法是错误的synchronized是对方法所在的对象进行同步的,而不是仅仅对方法本身起作用及如果a对象的A方法和B方法都是synchronized 那么A和B不可能同时执行lz的程序虽然看上去好像是两个synchronized的方法被同时执行了,但是其实并不是这样事实上doTimer()方法是在doButton1()方法中被调用的(当然不是lz主动调用的)这是被GUI程序的消息循环控制的 JOptionPane.showConfirmDialog在用户没有点按钮时,程序是处于消息循环中 而不是sleep 当timer事件到来时 消息循环线程 就会调用doTimer方法其实doButton1和doTimer都是被消息循环线程调用的 在doTimer中添加一句new Throwable().printStackTrace();这样就可以看到doTimer方法的调用堆栈,你可以看到doTimer方法是从doButton1方法调用过来的 多谢polarman,说得有道理,我看了printStackTrace的输出,确实是doButton1调用过来的,此时相当于从一个同步函数调用另一个同步函数,所以能顺利进入。而且我把mainTimer.start();调用移动到TestSyn的构造函数中,同时把mainTimer.stop();从doTimer中删掉,发现结果是一样的,消息框正在显示时一样会3秒钟输出一次。对这种现象不知有没有什么通用的理论可以描述?或者在什么文章中有描述? 请高手指点下cvs如何做统一版本 正则问题 关于web.xml的配制问题 这段代码什么意思? Document类是可串行化的么?可以在远程对象中传递么? 学java要下jdk 现在最新的是什么版啊 怎么让Eclipse支持JDK1.5? #########关于String和StringBuffer,知道的人进来########### Java中的Udp通讯问题 (可以加分 请说明) 想学JAVA,应该装什么版本的工具,哪能下载? 自己写了一个正则表达式工具(2) 100分求 怎么实现一个能够显示对话的窗口?
我blog中有一个《Java线程之线程同步》,你可以参考下:
http://blog.csdn.net/mq612/archive/2007/03/04/1520583.aspx
import java.awt.event.*;
import javax.swing.*;
//import javax.swing.JOptionPane;public class TestSyn extends JFrame
{
private ActionListener alButton;
private JButton jbB1,jbB2;
private Timer mainTimer;
public TestSyn()
{
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setTitle("TestSyn");
alButton=new ButtonListener(this);
jbB1=new JButton("Button1");
jbB1.addActionListener(alButton);
jbB2=new JButton("Button2");
jbB2.addActionListener(alButton);
Container cp=getContentPane();
GridBagLayout gbl=new GridBagLayout();
cp.setLayout(gbl);
GridBagConstraints gbc=new GridBagConstraints(); gbc.fill=GridBagConstraints.BOTH;
gbc.weightx=1.0;
gbc.weighty=0.0;
gbc.gridwidth=1;
gbc.insets=new Insets(5,2,5,2); cp.add(jbB1);
cp.add(jbB2);
setSize(320,320);
setVisible(true);
mainTimer=new Timer(3000,null);
mainTimer.addActionListener(alButton);
}
public static void main(String args[])
{
TestSyn mainFrame=new TestSyn();
}
public JButton getButton1()
{
return jbB1;
}
public JButton getButton2()
{
return jbB2;
}
public Timer getTimer()
{
return mainTimer;
}
synchronized public void doButton1()
{
mainTimer.start();
JOptionPane.showConfirmDialog
(this,"In doButton1","ABC",
JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
System.out.println("in doButton1()!");
}
public void doButton2()
{
System.out.println("in doButton2()!");
}
synchronized public void doTimer()
{
System.out.println("in doTimer()!");
mainTimer.stop();
}
}class ButtonListener implements ActionListener
{
private TestSyn testsyn; public ButtonListener(TestSyn ts)
{
testsyn=ts;
}
public void actionPerformed(ActionEvent e)
{
Object eventObject=e.getSource();
if(eventObject==testsyn.getButton1())
testsyn.doButton1();
else if(eventObject==testsyn.getButton2())
testsyn.doButton2();
else if(eventObject==testsyn.getTimer())
testsyn.doTimer();
}
}在JBuilder下运行时,发现按下button1后,显示消息框,在不退出消息框的情况下,3秒后依然会显示in doTimer()!信息,这不是synchronized不起作用了吗?还是定时器有什么“特权”?
你说的问题, 我想应该是JOptionPane显示出来的对话框不是Modal模式的, 因此后台的Timer仍然在反复执行. 如果你换一个Modal方式的JDialog跳出来, 试试看, 在Dialog还没有关掉的情况下是不是doTimer方法仍然被执行呢?
synchronized是对方法所在的对象进行同步的,而不是仅仅对方法本身起作用
及如果a对象的A方法和B方法都是synchronized 那么A和B不可能同时执行lz的程序虽然看上去好像是两个synchronized的方法被同时执行了,但是其实并不是这样
事实上doTimer()方法是在doButton1()方法中被调用的(当然不是lz主动调用的)
这是被GUI程序的消息循环控制的 JOptionPane.showConfirmDialog在用户没有点按钮时,程序是处于消息循环中 而不是sleep 当timer事件到来时 消息循环线程 就会调用doTimer方法
其实doButton1和doTimer都是被消息循环线程调用的
new Throwable().printStackTrace();这样就可以看到doTimer方法的调用堆栈,你可以看到doTimer方法是从doButton1方法调用过来的
多谢polarman,说得有道理,我看了printStackTrace的输出,确实是doButton1调用过来的,此时相当于从一个同步函数调用另一个同步函数,所以能顺利进入。而且我把mainTimer.start();调用移动到TestSyn的构造函数中,同时把mainTimer.stop();从doTimer中删掉,发现结果是一样的,消息框正在显示时一样会3秒钟输出一次。对这种现象不知有没有什么通用的理论可以描述?或者在什么文章中有描述?