📄 tij0156.html
字号:
}
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font>
setCircleSize(<font color="#0000ff">int</font> newSize) {
cSize = newSize;
}
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> String getBangText() {
<font color="#0000ff">return</font> text;
}
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font>
setBangText(String newText) {
text = newText;
}
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">int</font> getFontSize() {
<font color="#0000ff">return</font> fontSize;
}
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font>
setFontSize(<font color="#0000ff">int</font> newSize) {
fontSize = newSize;
}
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> Color getTextColor() {
<font color="#0000ff">return</font> tColor;
}
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font>
setTextColor(Color newColor) {
tColor = newColor;
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> paint(Graphics g) {
g.setColor(Color.black);
g.drawOval(xm - cSize/2, ym - cSize/2,
cSize, cSize);
}
<font color="#009900">// This is a multicast listener, which is</font>
<font color="#009900">// more typically used than the unicast</font>
<font color="#009900">// approach taken in BangBean.java:</font>
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font> addActionListener (
ActionListener l) {
actionListeners.addElement(l);
}
<font color="#0000ff">public</font> <font color="#0000ff">synchronized</font> <font color="#0000ff">void</font> removeActionListener(
ActionListener l) {
actionListeners.removeElement(l);
}
<font color="#009900">// Notice this isn't synchronized:</font>
<font color="#0000ff">public</font> <font color="#0000ff">void</font> notifyListeners() {
ActionEvent a =
<font color="#0000ff">new</font> ActionEvent(BangBean2.<font color="#0000ff">this</font>,
ActionEvent.ACTION_PERFORMED, <font color="#0000ff">null</font>);
Vector lv = <font color="#0000ff">null</font>;
<font color="#009900">// Make a copy of the vector in case someone</font>
<font color="#009900">// adds a listener while we're </font>
<font color="#009900">// calling listeners:</font>
<font color="#0000ff">synchronized</font>(<font color="#0000ff">this</font>) {
lv = (Vector)actionListeners.clone();
}
<font color="#009900">// Call all the listener methods:</font>
<font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i < lv.size(); i++) {
ActionListener al =
(ActionListener)lv.elementAt(i);
al.actionPerformed(a);
}
}
<font color="#0000ff">class</font> ML <font color="#0000ff">extends</font> MouseAdapter {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> mousePressed(MouseEvent e) {
Graphics g = getGraphics();
g.setColor(tColor);
g.setFont(
<font color="#0000ff">new</font> Font(
"TimesRoman", Font.BOLD, fontSize));
<font color="#0000ff">int</font> width =
g.getFontMetrics().stringWidth(text);
g.drawString(text,
(getSize().width - width) /2,
getSize().height/2);
g.dispose();
notifyListeners();
}
}
<font color="#0000ff">class</font> MM <font color="#0000ff">extends</font> MouseMotionAdapter {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> mouseMoved(MouseEvent e) {
xm = e.getX();
ym = e.getY();
repaint();
}
}
<font color="#009900">// Testing the BangBean2:</font>
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
BangBean2 bb = <font color="#0000ff">new</font> BangBean2();
bb.addActionListener(<font color="#0000ff">new</font> ActionListener() {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e){
System.out.println("ActionEvent" + e);
}
});
bb.addActionListener(<font color="#0000ff">new</font> ActionListener() {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e){
System.out.println("BangBean2 action");
}
});
bb.addActionListener(<font color="#0000ff">new</font> ActionListener() {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e){
System.out.println("More action");
}
});
Frame aFrame = <font color="#0000ff">new</font> Frame("BangBean2 Test");
aFrame.addWindowListener(<font color="#0000ff">new</font> WindowAdapter(){
<font color="#0000ff">public</font> <font color="#0000ff">void</font> windowClosing(WindowEvent e) {
System.exit(0);
}
});
aFrame.add(bb, BorderLayout.CENTER);
aFrame.setSize(300,300);
aFrame.setVisible(<font color="#0000ff">true</font>);
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Adding
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to the methods is an easy change. However, notice in <A NAME="Index2512"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addActionListener( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and <A NAME="Index2513"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>removeActionListener( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ActionListener</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
are now added to and removed from a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so you can have as many as you want.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see that the method <A NAME="Index2514"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notifyListeners( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
It can be called from more than one thread at a time. It’s also possible
for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addActionListener( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>removeActionListener( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to be called in the middle of a call to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notifyListeners( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which is a problem since it traverses the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector
actionListeners
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
To alleviate the problem, the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is cloned inside a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
clause and the clone is traversed. This way the original
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can be manipulated without impact on
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>notifyListeners( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method is also not <A NAME="Index2515"></A><A NAME="Index2516"></A><A NAME="Index2517"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Deciding whether to synchronize overridden methods is not as clear as when
you’re just adding your own methods. In this example it turns out that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
seems to work OK whether it’s
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or not. But the issues you must consider are:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Does
the method modify the state of “critical” variables within the
object? To discover whether the variables are “critical” you must
determine whether they will be read or set by other threads in the program. (In
this case, the reading or setting is virtually always accomplished via
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods, so you can just examine those.) In the case of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
no modification takes place.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Does
the method depend on the state of these “critical” variables? If a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method modifies a variable that your method uses, then you might very well want
to make your method
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
as well. Based on this, you might observe that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>cSize</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is changed by
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods and therefore
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
should be
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Here, however, you can ask “What’s the worst thing that will happen
if
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>cSize</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is changed during a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">?”
When you see that it’s nothing too bad, and a transient effect at that,
it’s best to leave
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
un-
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to prevent the extra overhead from the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method call.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> A
third clue is to notice whether the base-class version of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which it isn’t. This isn’t an airtight argument, just a clue. In
this case, for example, a field that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>is</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
changed via
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods (that is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>cSize</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)
has been mixed into the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
formula and might have changed the situation. Notice, however, that <A NAME="Index2518"></A><A NAME="Index2519"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
doesn’t inherit – that is, if a method is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in the base class then it
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>is
not
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
automatically
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in the derived class overridden version.
</FONT></OL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
test code in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TestBangBean2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
has been modified from that in the previous chapter to demonstrate the
multicast ability of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>BangBean2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
by adding extra listeners.
</FONT><a name="_Toc375545481"></a><a name="_Toc408018755"></a><P></DIV>
<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0155.html">Prev</a> | <a href="tij0157.html">Next</a>
</div>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -