我們現在已理解了同步
(
(
第一點很容易處理
//: BangBean
// You should write your Beans this way so they
// can run in a multithreaded environment
import java
import java
import java
import java
public class BangBean
implements Serializable {
private int xm
private int cSize =
private String text =
private int fontSize =
private Color tColor = Color
private Vector actionListeners = new Vector();
public BangBean
addMouseListener(new ML());
addMouseMotionListener(new MM());
}
public synchronized int getCircleSize() {
return cSize;
}
public synchronized void
setCircleSize(int newSize) {
cSize = newSize;
}
public synchronized String getBangText() {
return text;
}
public synchronized void
setBangText(String newText) {
text = newText;
}
public synchronized int getFontSize() {
return fontSize;
}
public synchronized void
setFontSize(int newSize) {
fontSize = newSize;
}
public synchronized Color getTextColor() {
return tColor;
}
public synchronized void
setTextColor(Color newColor) {
tColor = newColor;
}
public void paint(Graphics g) {
g
g
cSize
}
// This is a multicast listener
// more typically used than the unicast
// approach taken in BangBean
public synchronized void addActionListener (
ActionListener l) {
actionListeners
}
public synchronized void removeActionListener(
ActionListener l) {
actionListeners
}
// Notice this isn
public void notifyListeners() {
ActionEvent a =
new ActionEvent(BangBean
ActionEvent
Vector lv = null;
// Make a copy of the vector in case someone
// adds a listener while we
// calling listeners:
synchronized(this) {
lv = (Vector)actionListeners
}
// Call all the listener methods:
for(int i =
ActionListener al =
(ActionListener)lv.elementAt(i);
al.actionPerformed(a);
}
}
class ML extends MouseAdapter {
public void mousePressed(MouseEvent e) {
Graphics g = getGraphics();
g.setColor(tColor);
g.setFont(
new Font(
"TimesRoman", Font.BOLD, fontSize));
int width =
g.getFontMetrics().stringWidth(text);
g.drawString(text,
(getSize().width - width) /2,
getSize().height/2);
g.dispose();
notifyListeners();
}
}
class MM extends MouseMotionAdapter {
public void mouseMoved(MouseEvent e) {
xm = e.getX();
ym = e.getY();
repaint();
}
}
// Testing the BangBean2:
public static void main(String[] args) {
BangBean2 bb = new BangBean2();
bb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
System.out.println("ActionEvent" + e);
}
});
bb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
System.out.println("BangBean2 action");
}
});
bb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
System.out.println("More action");
}
});
Frame aFrame = new Frame("BangBean2 Test");
aFrame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
aFrame.add(bb, BorderLayout.CENTER);
aFrame.setSize(300,300);
aFrame.setVisible(true);
}
}
很容易就可以為方法添加synchronized。Tw.wiNgWIt.Com但注意在addActionListener()和removeActionListener()中,現在添加了ActionListener,並從一個Vector中移去,所以能夠根據自己願望使用任意多個。
我們注意到,notifyListeners()方法並未設為“同步”。可從多個線程中發出對這個方法的調用。另外,在對notifyListeners()調用的中途,也可能發出對addActionListener()和removeActionListener()的調用。這顯然會造成問題,因為它否定了Vector actionListeners。為緩解這個問題,我們在一個synchronized從句中“克隆”了Vector,並對克隆進行了否定。這樣便可在不影響notifyListeners()的前提下,對Vector進行操縱。
paint()方法也沒有設為“同步”。與單純地添加自己的方法相比,決定是否對過載的方法進行同步要困難得多。在這個例子中,無論paint()是否“同步”,它似乎都能正常地工作。但必須考慮的問題包括:
(1) 方法會在對象內部修改“關鍵”變量的狀態嗎?為判斷一個變量是否“關鍵”,必須知道它是否會被程序中的其他線程讀取或設置(就目前的情況看,讀取或設置幾乎肯定是通過“同步”方法進行的,所以可以只對它們進行檢查)。對paint()的情況來說,不會發生任何修改。
(2) 方法要以這些“關鍵”變量的狀態為基礎嗎?如果一個“同步”方法修改了一個變量,而我們的方法要用到這個變量,那麼一般都願意把自己的方法也設為“同步”。基於這一前提,大家可觀察到cSize由“同步”方法進行了修改,所以paint()應當是“同步”的。但在這裡,我們可以問:“假如cSize在paint()執行期間發生了變化,會發生的最糟糕的事情是什麼呢?”如果發現情況不算太壞,而且僅僅是暫時的效果,那麼最好保持paint()的“不同步”狀態,以避免同步方法調用帶來的額外開銷。
(3) 要留意的第三條線索是paint()基礎類版本是否“同步”,在這裡它不是同步的。這並不是一個非常嚴格的參數,僅僅是一條“線索”。比如在目前的情況下,通過同步方法(好cSize)改變的一個字段已合成到paint()公式裡,而且可能已改變了情況。但請注意,synchronized不能繼承——也就是說,假如一個方法在基礎類中是“同步”的,那麼在衍生類過載版本中,它不會自動進入“同步”狀態。
TestBangBean2中的測試代碼已在前一章的基礎上進行了修改,已在其中加入了額外的“聽眾”,從而演示了BangBean2的多造型能力。
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26188.html