同步关键字synchronized

同步关键字synchronized使用简洁,代码可维护性好。在JDK6中,性能也比早期的JDK有很大的改进。如果可以满足程序要求,应该首先考虑这种同步方式。

关键字synchronized一个最为常用的用法是锁定一个对象的方法:

public synchronized void method() {}

此时,当method()方法被调用时,调用线程必须首先获得当前对象的锁,若当前对象锁被其他线程持有,则调用线程会等待,方法结束后,对象锁会被释放。以上方法等价于:

  public void method1() {

       synchronized (this) {

       }

    }

  其次,使用synchronized还可以构造同步块,与同步方法相比,同步块可以更为精确的控制同步代码范围,缩小同步块。一个小的同步代码非常有利于锁的快进快出,从而使系统拥有更高的吞吐量。

public void method(SomeObject so) {

    some code here;

       synchronized (so) {

           }

       Other code here;

    }

  如以上代码所示,假设在同步块前后的代码段较为耗时,而他们又无需进行同步操作,将这些代码纳入整个同步代码块就会增加锁的等待时间,而将无需同步的代码块有效的剥离,仅同步必要的代码,有利于减小锁的竞争。

  此外synchronized方法还可以用于static函数:

  public synchronized static void method() {}

  当synchronized用于static函数时,相当于将锁加到当前Class对象上,因此,所有对该方法的调用,都必须获得Class对象的锁。

  虽然synchronized可以保证对象或者代码段的线程安全,但是仅使用synchronized还不足以控制拥有复杂逻辑的线程交互。为了实现多线程间的交互,还需要使用Object对象的wait()和notify()方法。

  函数wait()可以让线程等待当前对象上的通知(notify()被调用),在wait()过程中,线程会释放对象锁。它的典型用法如下:

  synchronized (obj) {

      while(<等待条件>) {

          obj.wait();

         …//收到通知后,继续执行

         }

       }

  首先,在使用wait()方法前,需要获得对象锁,以上代码片段就事先获得了obj的独占锁。其次wait()方法需要在一个循环中使用,指明跳出循环的条件。在wait()方法执行时,当前线程会释放obj的独占锁,共其他线程使用。

  当等待在obj上的线程收到一个obj.notify()时,它就能重新获得obj的独占锁,并继续运行。方法notify()将唤醒一个等待在当前对象上的线程。如果当前有多个线程,那么notify()方法将随机选择其中一个。

  下面代码实现了一个阻塞队列。该队列有两个方法,分别是pop和put()。方法pop()从队列中获取第一个数据,并返回,如果队列为空,则等待一个有效的对象;方法put()将一个对象保存到队列中,并通知一个在等待中的pop()方法。

package com.turing.currency.currencycontrolmethod.memodel;

import java.util.ArrayList;

import java.util.List;

public class BlockQueue {

    private List list = new ArrayList();

    public synchronized Object pop() throws InterruptedException {

       while (list.size() == 0) {

           this.wait();

       }

       if (list.size() > 0) {

           return list.remove(0);

       } else

           return null;

    }

    public synchronized void put(Object o) {

       list.add(o);

       this.notify();

    }

}

注意:

为了有效地控制线程间的协作,需要配合使用synchronized以及notify()和wait()等方法。

同步关键字synchronized的更多相关文章

  1. 新手向-同步关键字synchronized对this、class、object、方法的区别

    synchronized的语义 实验 分析 在看源代码时遇到多线程需要同步的时候,总是会看见几种写法,修饰方法.修饰静态方法.synchronized(Xxx.class).synchronized( ...

  2. Java中使用同步关键字synchronized需要注意的问题

    在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在 ...

  3. java多线程学习-同步(synchronized)

    (示例都是网上视频的) 假如两个线程同时调用一个方法输出字符串 public class SynchronizedTest extends Thread { public static void ma ...

  4. 多线程,线程同步,synchronized关键字的用法

    一.什么是多线程 Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorSe ...

  5. Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...

  6. 5.同步关键字(synchronized)

    同步关键字(synchronized): 多线程给我们提供方便的时候,也给整个编程增加了难度,尤其是对临界资源的控制,尤为重要. 一个在操作系统课上,老掉牙的事例,就把这种情况解释的明明白白. 一对夫 ...

  7. 多线程总结-同步之synchronized关键字

    目录 1.为什么要使用synchronized? 2.synchronized锁什么,加锁的目的是什么? 3.代码示例 3.1锁this和临界资源对象 3.2锁class类对象 3.3 什么时候锁临界 ...

  8. Java线程同步(synchronized)——卖票问题

    卖票问题通常被用来举例说明线程同步问题,在Java中,采用关键字synchronized关键字来解决线程同步的问题. Java任意类型的对象都有一个标志位,该标志位具有0,1两种状态,其开始状态为1, ...

  9. java多线程——同步块synchronized详解

    Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) 实例方法同步 静 ...

随机推荐

  1. iOS摄像头和相册-UIImagePickerController-浅析(转)

    iOS摄像头和相册-UIImagePickerController-浅析(转) 转自: http://blog.sina.com.cn/s/blog_7b9d64af0101cfd9.html 在一些 ...

  2. Fireworks Extension —— 开发篇(Dom模型)

    如上一篇博文所叙述的,一个很偶然的机会,我得知可以使用Javascript开发Fireworks插件,又注意到了视觉小伙伴的需求,于是便上手开发Fireworks Extension了. 很幸运的,在 ...

  3. 转:MFC中创建多线程

    MFC中创建多线程   MFC的多线程函数必须声明为静态的或者是全局函数(不同的在于全局函数不能访问类的私有静态成员,而静态类函数可以):但这样的线程函数只能访问静态的成员变量,要实现访问类的其他成员 ...

  4. 健身计划_from85to75

    第一天没什么好写的,这半年也没看什么书,就写写未来的规划好了. 当然是从最简单的健身计划开始写咯. 关键词:弹性 目标:减肥,上肢力量 时间:3-4次/周(Thur,Fri,Sat,Sun),1h-1 ...

  5. HTTP缓存机制[译文]

    本文翻译自: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching ,主要用于个人记录和共享,若有疏漏错误,请不吝指正,谢谢! 通过重用已 ...

  6. 认识Android

    安卓的特点开放性平等性无界性方便性硬件的丰富性 Android操作系统之中,一共将体系结构划分为四层:应用层(Application).应用框架层(Application Framework).系统运 ...

  7. delphi根据进程PID获取程序所在路径的函数(用OpenProcess取得句柄,用GetModuleFileNameEx取得程序名)

    uses psapi; {根据进程PID获取程序所在路径的函数}function GetProcessExePath(PID: Cardinal): string;varpHandle: THandl ...

  8. 【自由谈】城域网IPv6过渡技术——4v6场景技术总结(1)

    为什么会存在4v6应用场景?主要是从“云-管-端”的IPv6状态决定的,“云”侧IPv4类业务丰富,IPv6驱动力小,所以“云”在较长一段时间内还是以IPv4类业务为主.“管”侧的IPv6化程度高,设 ...

  9. Android源代码之Gallery专题研究(2)

    引言 上一篇文章已经解说了数据载入过程,接下来我们来看一看数据载入后的处理过程.依照正常的思维逻辑.当数据载入之后,接下来就应该考虑数据的显示逻辑. MVC显示逻辑 大家可能对J2EE的MVC架构比較 ...

  10. 怎么样学好C++

    声明:这篇文章非本人所写,转自:http://coolshell.cn/articles/4119.html 昨天写了一篇如何学好C语言,就有人回复问我如何学好C++,所以,我把我个人的一些学习经验写 ...