知识大全 Java如何共享资源
Posted 知
篇首语:人不能只做正确的选择,偶尔也得做一些喜欢的选择。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java如何共享资源相关的知识,希望对你有一定的参考价值。
Java如何共享资源 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
对一种特殊的资源——对象中的内存——Java提供了内建的机制来防止它们的冲突 由于我们通常将数据元素设为从属于private(私有)类 然后只通过方法访问那些内存 所以只需将一个特定的方法设为synchronized(同步的) 便可有效地防止冲突 在任何时刻 只可有一个线程调用特定对象的一个synchronized方法(尽管那个线程可以调用多个对象的同步方法) 下面列出简单的synchronized方法 synchronized void f() /* */ synchronized void g() /* */ 每个对象都包含了一把锁(也叫作 监视器 ) 它自动成为对象的一部分(不必为此写任何特殊的代码) 调用任何synchronized方法时 对象就会被锁定 不可再调用那个对象的其他任何synchronized方法 除非第一个方法完成了自己的工作 并解除锁定 在上面的例子中 如果为一个对象调用f() 便不能再为同样的对象调用g() 除非f()完成并解除锁定 因此 一个特定对象的所有synchronized方法都共享著一把锁 而且这把锁能防止多个方法对通用内存同时进行写操作(比如同时有多个线程) 每个类也有自己的一把锁(作为类的Class对象的一部分) 所以synchronized static方法可在一个类的范围内被相互间锁定起来 防止与static数据的接触 注意如果想保护其他某些资源不被多个线程同时访问 可以强制通过synchronized方访问那些资源 计数器的同步 装备了这个新关键字后 我们能够采取的方案就更灵活了 可以只为TwoCounter中的方法简单地使用synchronized关键字 下面这个例子是对前例的改版 其中加入了新的关键字 //: Sharing java // Using the synchronized keyword to prevent // multiple access to a particular resource import java awt *; import java awt event *; import java applet *; class TwoCounter extends Thread private boolean started = false; private TextField t = new TextField( ) t = new TextField( ); private Label l = new Label( count == count ); private int count = count = ; public TwoCounter (Container c) Panel p = new Panel(); p add(t ); p add(t ); p add(l); c add(p); public void start() if(!started) started = true; super start(); public synchronized void run() while (true) t setText(Integer toString(count ++)); t setText(Integer toString(count ++)); try sleep( ); catch (InterruptedException e) public synchronized void synchTest() Sharing incrementAccess(); if(count != count ) l setText( Unsynched ); class Watcher extends Thread private Sharing p; public Watcher (Sharing p) this p = p; start(); public void run() while(true) for(int i = ; i < p.s.length; i++) p.s[i].synchTest(); try sleep(500); catch (InterruptedException e) public class Sharing2 extends Applet TwoCounter2[] s; private static int accessCount = 0; private static TextField aCount = new TextField("0", 10); public static void incrementAccess() accessCount++; aCount.setText(Integer.toString(accessCount)); private Button start = new Button("Start"), observer = new Button("Observe"); private boolean isApplet = true; private int numCounters = 0; private int numObservers = 0; public void init() if(isApplet) numCounters = Integer.parseInt(getParameter("size")); numObservers = Integer.parseInt( getParameter("observers")); s = new TwoCounter2[numCounters]; for(int i = 0; i < s.length; i++) s[i] = new TwoCounter2(this); Panel p = new Panel(); start.addActionListener(new StartL()); p.add(start); observer.addActionListener(new ObserverL()); p.add(observer); p.add(new Label("Access Count")); p.add(aCount); add(p); class StartL implements ActionListener public void actionPerformed(ActionEvent e) for(int i = 0; i < s.length; i++) s[i].start(); class ObserverL implements ActionListener public void actionPerformed(ActionEvent e) for(int i = 0; i < numObservers; i++) new Watcher2(Sharing2.this); public static void main(String[] args) Sharing2 applet = new Sharing2(); // This isn\'t an applet, so set the flag and // produce the parameter values from args: applet.isApplet = false; applet.numCounters = (args.length == 0 ? 5 : Integer.parseInt(args[0])); applet.numObservers = (args.length < 2 ? 5 : Integer.parseInt(args[1])); Frame aFrame = new Frame("Sharing2"); aFrame.addWindowListener( new WindowAdapter() public void windowClosing(WindowEvent e) System.exit(0); ); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(350, applet.numCounters *100); applet.init(); applet.start(); aFrame.setVisible(true); 我们注意到无论run()还是synchTest()都是“同步的”。WInGWit.如果只同步其中的一个方法,那么另一个就可以自由忽视对象的锁定,并可无碍地调用。所以必须记住一个重要的规则:对于访问某个关键共享资源的所有方法,都必须把它们设为synchronized,否则就不能正常地工作。 现在又遇到了一个新问题。Watcher2永远都不能看到正在进行的事情,因为整个run()方法已设为“同步”。而且由于肯定要为每个对象运行run(),所以锁永远不能打开,而synchTest()永远不会得到调用。之所以能看到这一结果,是因为accessCount根本没有变化。 为解决这个问题,我们能采取的一个办法是只将run()中的一部分代码隔离出来。想用这个办法隔离出来的那部分代码叫作“关键区域”,而且要用不同的方式来使用synchronized关键字,以设置一个关键区域。Java通过“同步块”提供对关键区域的支持;这一次,我们用synchronized关键字指出对象的锁用于对其中封闭的代码进行同步。如下所示: synchronized(syncObject) // This code can be accessed by only // one thread at a time, assuming all // threads respect syncObject\'s lock 在能进入同步块之前,必须在synchObject上取得锁。如果已有其他线程取得了这把锁,块便不能进入,必须等候那把锁被释放。 可从整个run()中删除synchronized关键字,换成用一个同步块包围两个关键行,从而完成对Sharing2例子的修改。但什么对象应作为锁来使用呢?那个对象已由synchTest()标记出来了——也就是当前对象(this)!所以修改过的run()方法象下面这个样子: public void run() while (true) synchronized(this) t1.setText(Integer.toString(count1++)); t2.setText(Integer.toString(count2++)); try sleep(500); catch (InterruptedException e) 这是必须对Sharing2.java作出的唯一修改,我们会看到尽管两个计数器永远不会脱离同步(取决于允许Watcher什么时候检查它们),但在run()执行期间,仍然向Watcher提供了足够的访问权限。 当然,所有同步都取决于程序员是否勤奋:要访问共享资源的每一部分代码都必须封装到一个适当的同步块里。 2. 同步的效率 由于要为同样的数据编写两个方法,所以无论如何都不会给人留下效率很高的印象。看来似乎更好的一种做法是将所有方法都设为自动同步,并完全消除synchronized关键字(当然,含有synchronized run()的例子显示出这样做是很不通的)。但它也揭示出获取一把锁并非一种“廉价”方案——为一次方法调用付出的代价(进入和退出方法, cha138/Article/program/Java/JSP/201311/19487相关参考
知识大全 Java进阶 Java应用程序中动态分配CPU资源[2]
Java进阶Java应用程序中动态分配CPU资源[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 Java进阶 Java应用程序中动态分配CPU资源[1]
Java进阶Java应用程序中动态分配CPU资源[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 Java进阶 Java应用程序中动态分配CPU资源[3]
Java进阶Java应用程序中动态分配CPU资源[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
Java多线程共享数据、同步、通信 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一线程共享数据
JAVA远程访问共享目录 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 相关知识介绍 SMB
用JAVA访问共享文件系统 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 前言 在Micros
Java多线程锁如何进行数据同步共享 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Java多线
Java多线程进程应对同一程序运行资源 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Java多
共享内存在Java中的实现和应用 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 共享内存对应应用
通过E-mail共享Java对象 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! JDK的新功能序