快速业务通道

Java多线程初学者指南(10):使用Synchronized关键字同步类方法 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-24

Java多线程初学者指南(10):使用Synchronized关键字同步类方法

时间:2010-02-01 BlogJava 银河使者

要想解决“脏数据”的问题,最简单的方法就是使用synchronized关键字来使run方法同步,代码如下:

public synchronized void run() { }

从上面的代码可以看出,只要在void和public之间加上synchronized关键字,就可以使run方法同步,也就是说,对于同一个Java类的对象实例,run方法同时只能被一个线程调用,并当前的run执行完后,才能被其他的线程调用。即使当前线程执行到了run方法中的yield方法,也只是暂停了一下。由于其他线程无法执行run方法,因此,最终还是会由当前的线程来继续执行。先看看下面的代码:

sychronized关键字只和一个对象实例绑定 class Test {  public synchronized void method()  {  } } public class Sync implements Runnable {  private Test test;  public void run()  {   test.method();  }  public Sync(Test test)  {   this.test = test;  }  public static void main(String[] args) throws Exception  {   Test test1 =  new Test();   Test test2 =  new Test();   Sync sync1 = new Sync(test1);   Sync sync2 = new Sync(test2);   new Thread(sync1).start();   new Thread(sync2).start();  }

在Test类中的method方法是同步的。但上面的代码建立了两个Test类的实例,因此,test1和test2的method方法是分别执行的。要想让method同步,必须在建立Sync类的实例时向它的构造方法中传入同一个Test类的实例,如下面的代码所示:

Sync sync1 = new Sync(test1);

不仅可以使用synchronized来同步非静态方法,也可以使用synchronized来同步静态方法。如可以按如下方式来定义method方法:

class Test  {  public static synchronized void method() {  } }

建立Test类的对象实例如下:

Test test = new Test();

Java多线程初学者指南(10):使用Synchronized关键字同步类方法(2)

时间:2010-02-01 BlogJava 银河使者

对于静态方法来说,只要加上了synchronized关键字,这个方法就是同步的,无论是使用test.method(),还是使用Test.method()来调用method方法,method都是同步的,并不存在非静态方法的多个实例的问题。

在23种设计模式中的单件(Singleton)模式如果按传统的方法设计,也是线程不安全的,下面的代码是一个线程不安全的单件模式。

package test; // 线程安全的Singleton模式 class Singleton {  private static Singleton sample;  private Singleton()  {  }  public static Singleton getInstance()  {   if (sample == null)   {    Thread.yield(); // 为了放大Singleton模式的线程不安全性    sample = new Singleton();   }   return sample;  } } public class MyThread extends Thread {  public void run()  {   Singleton singleton = Singleton.getInstance();   System.out.println(singleton.hashCode());  }  public static void main(String[] args)  {   Thread threads[] = new Thread[5];   for (int i = 0; i < threads.length; i++)    threads[i] = new MyThread();   for (int i = 0; i < threads.length; i++)    threads[i].start();  } }

在上面的代码调用yield方法是为了使单件模式的线程不安全性表现出来,如果将这行去掉,上面的实现仍然是线程不安全的,只是出现的可能性小得多。

程序的运行

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号