知识大全 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多线程共享数据、同步、通信

Java多线程共享数据、同步、通信  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一线程共享数据

知识大全 JAVA远程访问共享目录

JAVA远程访问共享目录  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  相关知识介绍  SMB 

知识大全 用JAVA访问共享文件系统

用JAVA访问共享文件系统  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  前言  在Micros

知识大全 Java多线程锁如何进行数据同步共享

Java多线程锁如何进行数据同步共享  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多线

知识大全 Java多线程进程应对同一程序运行资源

Java多线程进程应对同一程序运行资源  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多

知识大全 共享内存在Java中的实现和应用

共享内存在Java中的实现和应用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  共享内存对应应用

知识大全 通过E-mail共享Java 对象

通过E-mail共享Java对象  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  JDK的新功能序