`

Java synchronize用法(转)

    博客分类:
  • Java
 
阅读更多

在多个并发线程之间共用资源,就需要进行同步处理。Java虚拟机通过给每个对象加锁的方式实现多线程的同步处理,这里的对象包括类对象和实例对象。一个类的静态成员方法和静态成员域隶属于类对象,一个类的非静态成员域和非静态成员方法隶属于类的实例对象。
   Java 虚拟机为每个对象配备一把锁和一个等候集,对象锁内部锁住的是一些同步方法个同步语句块。一个方法要成为同步方法只要给该方法加上修饰词synchronized就可以了,同步语句块的定义格式为
   synchronized(引用类型的表达式)
其中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方法;

 

synchronized 的语法:
synchronized 可以作为一个method的修饰符,也可以一段代码里出现,先说在代码里出:
  其语法是
   synchronized(xx) {
    //your code
   }
   这个xx需要是一个Object,只要是一个Object就行,如:
        String s="haha";
        synchronized(s) {
           //your code
        }
   不是Object不行,如:
        int n=3;
        synchronized(n) {
                //your code
        }
   是不可以的,有autoboxing也不行。
   如果你理解this的含义,那么
    synchronized(this) {
        //your code
    }
   也很好理解,它需要一个Object,而this是一个特殊的Object,当然可以这样用。
再说synchronized 修饰 method的情况,如果synchronized修饰一个非static的method,
如:
    public synchronized void aMethod() {
        //some code
    }
相当于:
    public void aMethod() {
        synchronized(this) {
           //some code
        }
    }
修饰一个 static的method,
如:
    public static synchronized void aMethod() {
        //some code
    }
相当于:
    public static synchronized void aMethod() {
        synchronized(XX.class) {
           //some code
        }
    }
XX是这个方法所在的类,XX.class 也是一个Object,类型是Class而已,在一个
ClassLoader里,它是唯一的,就是独一无二的object
    总之synchronized的语法可以统一为: synchronized(a var) { do something }


synchronized 的语义:
这是我自己的理解,
   synchronized(xx) {
      //your code
   }
的语义是,在xx这个Object的“授权”、“名义”、 “面子”下,执行 your code。要注
意的是,xx只能授权给一个人(线程),当xx授权给某个人执行后,就不能再授权给别人了
。 当那个人执行完那段代码后,xx才能继续授权给其它人执行,可以理解为,别人在xx的
授权下,执行完这段代码后,把这个权利又还给xx了。 当xx不能授权给一个人时,这个人
必须等在这里,知道xx可以授权给它。 (上面说的人都是线程)


synchronized 的作用:
synchronized是用在多线程环境中的,作用简单的说,就是不允许 “某些” 线程 同时执
行到一段代码里。 这个 “某些”线程 怎么界定? 是由那个xx object决定的,就是当两
个线程执行到 synchronized的时候,需要同一个Object授权时,这两个线程不能同时执行
到需要授权的代码。
  极端情况是 系统你所有的线程都不能执行到这段代码里,那么你就选一个极端唯一的
object作为xx,一般选Class object,如:
synchronized(String.class) {
}

具体到应用比较复杂,举两个例子:
1:

public class Test1 implements Runnable {

    public void run() {
        synchronized(this) {
            try {
                System.out.println("Thread running++++++");
                System.out.println(System.currentTimeMillis());
                Thread.sleep(2000);
                System.out.println(System.currentTimeMillis());
                System.out.println("Thread finished++++++");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Test1 test=new Test1();
        for(int i=0;i<10;i++) {
            new Thread(test).start();
        }
    }
}


2:
public class Test1 implements Runnable {

    public void run() {
        synchronized(this) {
            try {
                System.out.println(System.currentTimeMillis());
                Thread.sleep(2000);
                System.out.println(System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++) {
            new Thread(new Test1()).start();
        }
    }
}

两个例子中,都有一段synchronized的代码。
在1中,main方法中创建的10个线程 不能同时进入到那段代码执行,因为这10个线程需要让
同一个object授权
而在2中,main方法中创建的10个线程 可以同时进入到那段代码执行,因为10个线程是让不同
的object授权的,均授权成功,同时进入到那段代码执行

 

分享到:
评论

相关推荐

    java synchronize 线程同步

    在引申的例子中,通过定义一个静态的`lock`对象,然后在同步代码块中使用它,确保了所有线程在执行`execute()`方法时都会获取这把全局锁,从而实现了同步。 ```java public class TestThread { private static ...

    Java synchronize线程安全测试

    在Java中,synchronize关键字的使用可以分为两种情况:一种是修饰方法,另一种是修饰代码块。这两种情况都可以用来解决线程安全问题,但是它们有所不同。修饰方法可以将整个方法锁定,使得在同一时间内只有一个线程...

    Java 中synchronize函数的实例详解

    在Java编程语言中,`synchronized`关键字用于...在上述示例中,`synchronized` 方法的使用保证了线程安全,避免了并发问题。在实际开发中,合理地使用`synchronized`可以帮助我们构建出更健壮、更稳定的多线程程序。

    synchronized关键字的用法详解

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

    Java对象锁和类锁全面解析(多线程synchronize

    Java对象锁和类锁是Java多线程编程中至关重要的概念,它们是通过`synchronized`关键字来实现的,用于确保代码在并发环境下的线程安全。在这个全面解析中,我们将深入探讨这两个锁机制,理解它们的工作原理以及如何在...

    synchronize.zip

    在IT行业中,尤其是在Java编程领域,`synchronize.zip`这个文件名可能暗示着一个与同步相关的项目或代码库。从提供的文件列表来看,我们可以推测这是一个关于处理店铺操作任务的系统,比如更新店铺任务...

    Java重写重载线程

    ### Java中的方法重载与重写以及线程概念详解 #### 一、方法重载(Overloading) 在Java中,**方法重载**是指在同一个类中定义多个具有相同名称但参数列表不同的方法。这里提到的“参数列表不同”不仅包括参数的...

    synchronized用法大全实例

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

    synchronize.pdf

    标题 "synchronize.pdf" 和描述 "synchronize详解" 显示该文档专注于Java编程语言中关键字 synchronized 的使用和机制。Synchronized 关键字是Java中用于控制多线程并发访问共享资源的一个核心关键字,确保同一时间...

    java开发坦克大战(实用应用文).doc

    在 Java 中,我们可以使用 Thread 类来创建线程,并使用 synchronize 关键字来实现线程同步。 Java 文件 I/O 操作: Java 提供了多种文件 I/O 操作技术,包括 InputStream、OutputStream、Reader、Writer 等。在 ...

    java 线程同步 信号量控制同步

    synchronized 关键字可以用来锁定对象或方法,防止多个线程同时访问同一个共享资源。 在 Java 中,还有其他线程同步机制,如volatile 变量、Atomic 变量、Lock 接口等。这些机制可以用于解决不同类型的线程同步问题...

    JAVA开发常用英语单词

    5. Synchronize(同步):Java中同步关键字,用于控制并发访问共享资源的代码块,保证多线程安全。 6. Stack(栈):在计算机科学中,栈是一种数据结构,支持后进先出的操作模式。在Java虚拟机(JVM)中,Java栈...

    java面试题库(非常全面).

    15. **Java性能优化**:代码级别的优化技巧,如避免过度使用 synchronize,理解CPU缓存和内存层次结构对性能的影响。 16. **JUnit测试**:单元测试的概念,如何编写和执行JUnit测试用例,以及Mockito等工具的使用。...

    第-章-JAVA多线程优秀文档.pptx

    * synchronize 锁机制:使用 synchronize 关键字来锁定某个对象,以确保线程安全。 * wait() 和 notify() 方法:使用 wait() 方法来使线程等待某个事件的发生,并使用 notify() 方法来唤醒等待的线程。 * Lock 接口...

    java程序员面试题

    最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概...

    Java面试思维导图.pdf

    这些I/O模型对Java网络编程提供了不同的性能和使用场景。 ### 分布式系统 分布式系统部分提到了Spring Cloud、ZooKeeper、Redis等组件。Spring Cloud是用于构建分布式系统的工具集,ZooKeeper是一种可靠的协调服务...

    java关键字和标识符的使用

    Java 关键字和标识符的使用 Java 编程语言中,关键字和标识符是两个非常重要的概念,它们在编程中扮演着不同的角色。关键字是 Java 语言中预定义的单词,它们具有特殊的含义和用途,而标识符则是开发者自行定义的...

    java技术储备,如何提升自己

    1. Synchronize 和 Lock:了解 Synchronize 和 Lock 的区别与用法。 2. wait() 和 notify():了解 wait() 和 notify() 的区别和用法。 3. volatile:深入理解 volatile 关键字的作用和实现机制。 4. CAS:了解 CAS...

    Java Thin-Client Programming

    - **使用方法:**详细说明了如何使用互斥锁来防止多个线程同时访问同一资源。 - **优点:**能够有效控制对共享资源的访问,避免数据竞争条件。 - **条件变量(Condition Variables)** - **定义:**条件变量是一...

Global site tag (gtag.js) - Google Analytics