`
ableouou
  • 浏览: 73658 次
  • 性别: Icon_minigender_2
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

转载 :synchronized用法

阅读更多
在java编程思想中对synchronized的一点解释:
1、synchronized关键字的作用域有二种:
1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;

3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;


----------------------------------------------------------------------------
java里面synchronized用法

synchronized的一个简单例子

public class TextThread
{

/**
  * @param args
  */
public static void main(String[] args)
{
  // TODO 自动生成方法存根
        TxtThread tt = new TxtThread();
        new Thread(tt).start();
        new Thread(tt).start();
        new Thread(tt).start();
        new Thread(tt).start();
}

}
class TxtThread implements Runnable
{
int num = 100;
String str = new String();
public void run()
{
  while (true)
  {
   synchronized(str)
   {
   if (num>0)
   {
    try
    {
     Thread.sleep(10);
    }
    catch(Exception e)
    {
     e.getMessage();
    }
    System.out.println(Thread.currentThread().getName()+ "this is "+ num--);
   }
   }
  }
}
}

上面的例子中为了制造一个时间差,也就是出错的机会,使用了Thread.sleep(10)


Java对多线程的支持与同步机制深受大家的喜爱,似乎看起来使用了synchronized关键字就可以轻松地解决多线程共享数据同步问题。到底如何?――还得对synchronized关键字的作用进行深入了解才可定论。

总的说来,synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。

在进一步阐述之前,我们需要明确几点:

A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。

B.每个对象只有一个锁(lock)与之相关联。

C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

接着来讨论synchronized用到不同地方对代码产生的影响:



假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都可以调用它们。



1.  把synchronized当作函数修饰符时,示例代码如下:

Public synchronized void methodAAA()

{

//….

}

这也就是同步方法,那这时synchronized锁定的是哪个对象呢?它锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却可以任意调用这个被加了synchronized关键字的方法。

上边的示例代码等同于如下代码:

public void methodAAA()

{

synchronized (this)      //  (1)

{

       //…..

}

}

(1)处的this指的是什么呢?它指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才可以调用P1的同步方法,而对P2而言,P1这个锁与它毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造成数据混乱:(

2.同步块,示例代码如下:

            public void method3(SomeObject so)

              {

                     synchronized(so)

{

       //…..

}

}

这时,锁就是so这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁:

class Foo implements Runnable

{

       private byte[] lock = new byte[0];  // 特殊的instance变量

    Public void methodA()

{

       synchronized(lock) { //… }

}

//…..

}

注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

3.将synchronized作用于static 函数,示例代码如下:

      Class Foo

{

public synchronized static void methodAAA()   // 同步的static 函数

{

//….

}

public void methodBBB()

{

       synchronized(Foo.class)   //  class literal(类名称字面常量)

}

       }

   代码中的methodBBB()方法是把class literal作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。

记得在《Effective Java》一书中看到过将 Foo.class和 P1.getClass()用于作同步锁还不一样,不能用P1.getClass()来达到锁这个Class的目的。P1指的是由Foo类产生的对象。

可以推断:如果一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时,不会构成同步,因为它们的锁都不一样。A方法的锁是Obj这个对象,而B的锁是Obj所属的那个Class。



小结如下:

搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程序。



还有一些技巧可以让我们对共享资源的同步访问更加安全:

1.  定义private 的instance变量+它的 get方法,而不要定义public/protected的instance变量。如果将变量定义为public,对象在外界可以绕过同步方法的控制而直接取得它,并改动它。这也是JavaBean的标准实现方式之一。

2.  如果instance变量是一个对象,如数组或ArrayList什么的,那上述方法仍然不安全,因为当外界对象通过get方法拿到这个instance对象的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。 这个时候就需要将get方法也加上synchronized同步,并且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了。

转自:http://xiaodiandian.iteye.com/blog/620653
分享到:
评论

相关推荐

    java里面synchronized用法.doc

    Java 中的 synchronized 用法详解 Java 中的 synchronized 关键字是用于解决多线程并发问题的重要工具之一。它可以被用于方法、代码块和变量上,以实现对共享资源的互斥访问控制。本文将对 Java 中的 synchronized ...

    并发编程原理学习:synchronized关键字.doc

    `synchronized`关键字可以用于修饰方法或作为同步代码块,其核心目标是保证线程对共享资源的访问具有互斥性和可见性,防止数据不一致和竞态条件。 ### 同步代码块 同步代码块的形式如下: ```java synchronized ...

    Java并发编程:Synchronized关键字深度解析

    本文深入探讨了Java中用于解决并发...通过对synchronized关键字的深入分析,本文为Java开发者提供了对并发编程中关键同步工具的全面理解,特别是在高并发场景下如何有效使用synchronized以确保线程安全和提高程序性能。

    java中synchronized用法

    "Java 中 synchronized 用法详解" Synchronized 是 Java 语言中用于解决多线程共享数据同步问题的关键字。它可以作为函数的修饰符,也可以作为函数内的语句,用于实现同步方法和同步语句块。在 Java 中,...

    Java并发编程:Synchronized及其实现原理

    以下将详细介绍Synchronized的使用及其实现原理。 一、Synchronized基本使用 1. 修饰普通方法 当Synchronized用于修饰非静态方法时,它会为每个对象实例创建一个锁,也称为实例锁或对象锁。当线程A调用该对象的...

    synchronized用法大全实例

    本实例大全将全面解析`synchronized`的使用方式,包括同步方法、同步语句块、类锁和对象锁。 ### 1. 同步方法 同步方法是通过在方法声明前加上`synchronized`关键字实现的。这样,同一时间只有一个线程可以执行该...

    java同步synchronized关键字用法示例

    - **代码块同步:** 也可以使用`synchronized`关键字来同步代码块,这样可以更细粒度地控制同步范围,提高程序性能。 ```java public void method() { synchronized (object) { // 代码块 } } ``` 这里的`object...

    synchronized关键字的用法详解

    `synchronized`关键字有两种主要的使用方式:一种是在方法声明中使用,另一种则是在代码块中使用。 ##### 1. synchronized方法 在方法声明中添加`synchronized`关键字,可以将整个方法体变成同步代码块。例如: `...

    Synchronized Multimedia Integration Language (SMIL 3.0)

    同步多媒体集成语言(Synchronized Multimedia Integration Language,简称SMIL,发音为“smile”),是一种基于XML的语言标准,用于创建交互式的多媒体演示。SMIL 3.0是该标准的第三个版本,它在前两个版本的基础上...

    6477638_Synchronized_instruction_advance.pdf

    CPU : Synchronized_instruction_advance

    Java:synchronized锁住的是代码还是对象

    Synchronized既可以对代码块使用,也可以加在整个方法上。  关键是,不要认为给方法或者代码段加上synchronized万事大吉,看下面一段代码: class Sync {  public synchronized void test() {  System.out...

    深入理解java中的synchronized关键字

    本文将深入探讨`synchronized`的两种主要用法:synchronized方法和synchronized块。 1. **synchronized 方法** synchronized方法是通过在方法声明前添加`synchronized`关键字来定义的。例如: ```java public ...

    Java synchronized使用案例

    一、`synchronized`的基本用法 1. **方法同步**:在方法声明前加上`synchronized`,整个方法都会被锁定,任何时刻只有一个线程能执行该方法。 ```java public synchronized void method() { // 方法体 } ``` 2. **...

    Synchronized关键字的用法

    - **实例方法**:可以直接将`synchronized`关键字放在实例方法前,此时该方法的锁为当前对象实例本身。 ```java public synchronized void method() { // 同步方法体 } ``` - 当一个线程调用此方法时,会锁定...

    volatile和synchronized的区别

    在Java中,为了保证多线程环境下数据的一致性和安全性,可以采用两种主要的方法:`synchronized`和`volatile`。 ##### 1. synchronized关键字 `synchronized`是一种基于锁的同步机制,它可以应用于方法或者代码块...

    synchronized关键字的实质及用法

    本文将详细探讨`synchronized`的关键特性、用法以及它在实际开发中的应用。 1. **synchronized的两种使用方式** - **方法同步**:在方法声明前加上`synchronized`关键字,这将使得整个方法成为同步方法,每次只有...

    Synchronized 终极说明教程

    1. 方法同步:通过在方法声明前添加`synchronized`关键字,整个方法体将被锁定。例如: ```java public synchronized void method() { // ... } ``` 这样,同一时间只能有一个线程执行该方法。 2. 代码块同步:...

    Java实习生面试复习(七):synchronized和ReentrantLock的学习

    4. **锁的粒度更细**:`synchronized`可以修饰方法或代码块,而`ReentrantLock`只能通过`lock()`和`unlock()`方法来控制代码块,这使得`ReentrantLock`的使用更加灵活。 在性能方面,`synchronized`在JDK 1.6及以后...

    [JAVA][synchronized的使用]

    本篇文章将深入探讨`synchronized`的使用,包括其基本原理、使用方式以及实际应用场景。 1. **synchronized的基本原理** `synchronized`关键字在Java中提供了互斥访问,也就是说,当一个线程进入一个对象的`...

    Android synchronized 测试案例

    本测试案例深入探讨了`synchronized`的使用方法,包括同步单个对象、同步多个对象以及成功与失败的场景对比。 一、`synchronized`关键字的基本概念 `synchronized`关键字可以修饰方法或用作代码块,其主要作用是...

Global site tag (gtag.js) - Google Analytics