日期:2011-03-22 16:16:00 来源:本站整理
回想Java Beans[Java编程]
本文“回想Java Beans[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
我们目前已理解了同步,接着可换从另一个角度来观察Java Beans.无论什么时刻成立了一个Bean,就必须假定它要在一个多线程的环境中运行.这意味着:
(1) 只要可行,Bean的全部大众办法都应同步.当然,这也带来了“同步”在运行期间的开销.若分外在乎这个问题,在关键区域中不会造成问题的办法便可保存为“差别步”,但注意这普通都不是非常简单判断.有资格的办法偏向于规模很小(以下例的getCircleSize())以及/大概“细小”.也就是说,这个办法调用在如此少的代码片里履行,以至于在履行期间对象不能改变.假如将这种办法设为“差别步”,大概对程序的履行速度不会有明显的影响.大概也将一个Bean的全部public办法都设为synchronized,并只有在保证分外必要、并且会造成一个差别的情形下,才将synchronized关键字删去.
(2) 假如将一个多造型事件送给一系列对那个事件感爱好的“听众”,必须假在列表中移动的时刻可以增添大概删除.
第一点很简单处理,但第二点需求考虑更多的东西.让我们从前一章供应的BangBean.java为例.在那个例子中,我们忽视了synchronized关键字(当时还没有引入呢),并将造型设为单造型,从而躲避了多线程的问题.在下面这个改正过的版本中,我们使其能在多线程环境中工作,并为事件采取了多造型技术:
很简单便可认为办法增添synchronized.但注意在addActionListener()和removeActionListener()中,目前增添了ActionListener,并从一个Vector中移去,所以可以按照自己希望利用肆意多个.//: BangBean2.java // You should write your Beans this way so they // can run in a multithreaded environment. import java.awt.*; import java.awt.event.*; import java.util.*; import java.io.*; public class BangBean2 extends Canvas implements Serializable { private int xm, ym; private int cSize = 20; // Circle size private String text = "Bang!"; private int fontSize = 48; private Color tColor = Color.red; private Vector actionListeners = new Vector(); public BangBean2() { 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.setColor(Color.black); g.drawOval(xm - cSize/2, ym - cSize/2, cSize, cSize); } // This is a multicast listener, which is // more typically used than the unicast // approach taken in BangBean.java: public synchronized void addActionListener ( ActionListener l) { actionListeners.addElement(l); } public synchronized void removeActionListener( ActionListener l) { actionListeners.removeElement(l); } // Notice this isn't synchronized: public void notifyListeners() { ActionEvent a = new ActionEvent(BangBean2.this, ActionEvent.ACTION_PERFORMED, null); Vector lv = null; // Make a copy of the vector in case someone // adds a listener while we're // calling listeners: synchronized(this) { lv = (Vector)actionListeners.clone(); } // Call all the listener methods: for(int i = 0; i < lv.size(); 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); } } ///:~
我们注意到,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的多造型本领.
以上是“回想Java Beans[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
- ·上一篇文章:java的表格
- ·下一篇文章:<b>Java若何同享资源</b>
- ·中查找“回想Java Beans”更多相关内容
- ·中查找“回想Java Beans”更多相关内容
评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论