- 浏览: 980150 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
Mr.Cheney:
去掉 UUID字符串中的“-” 直接replaceAll(&q ...
JAVA生成全局唯一ID 使用 java.util.UUID -
呜哩喵:
楼主nice
java中的时间操作 -
zxs6587:
Thinking inJava我读着好像说要建立基类对象啊!请 ...
创建子类的对象时也要创建其所有父类的对象? -
just_Word:
getFullYear
date.getyear -
JamesQian:
我觉得楼上的synchronized(this),notify ...
notify() wait()
在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()――这样,调用端得到的就是对象副本的引用了。
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()――这样,调用端得到的就是对象副本的引用了。
发表评论
-
关于数组和List之间相互转换的方法
2011-04-14 21:04 13841.List转换成为数组。( ... -
java的几种对象(PO,VO,DAO,BO,POJO)解释
2011-03-24 10:13 1346java的几种对象(PO,VO,DAO,BO,POJO)解释 ... -
switch
2010-12-02 19:02 11471 public class Switch { 2 ... -
优化的冒泡排序
2010-09-25 14:18 1371public static void bubble_Sort( ... -
java变量命名规则
2010-08-13 23:15 23721. 大小写有别,例如 a 和 A是两个变量 2. 长度任意 ... -
String.getBytes()的问题
2010-08-13 22:46 1650转载 http://java.chinaitlab.c ... -
tomcat 修改端口
2010-08-09 22:41 2008Tomcat端口修改: 在Tomcat安装目录下的conf目 ... -
tomcat 中增加用户名和密码
2010-08-09 22:41 1919原来的tomcat-user.xml是 <?xml ... -
Eclipse is running in a JRE, but a JDK is required
2010-07-28 09:30 15311 安装了maven插件,使用的时候老是有这样的提示: 08- ... -
安装Eclipse的maven插件
2010-07-27 11:01 1828Installing m2eclipse Core To i ... -
Attach Library Sources and Javadocs
2010-07-26 13:41 1929Attach Library Sources and Java ... -
maven 安装jaxb插件
2010-07-18 15:10 65711. Put your schemas ( ... -
java接受控制台输入
2010-07-16 13:45 2715import java.io.*; public c ... -
将xsd文件转化为java类
2010-07-10 15:31 2514最近有一个需求是把xsd文件中定义的数据类型转化为java类 ... -
jconsole attache sun glassfish
2010-06-13 17:04 1354To Set Up JConsole Connectivity ... -
suse下lamp的安装
2010-05-31 16:45 1566首先卸载suse缺省安装的apache2 主要是在网上看到人家 ... -
java的property配置文件的用法
2010-05-30 15:04 1146在我们平时写程序的时候,有些参数是经常改变的,而这种改变不是我 ... -
让ubuntu下的eclipse支持GBK编码
2010-05-30 14:38 1523今天,把windows下的工程导入到了Linux下eclips ... -
java路径中/的问题
2010-05-18 17:23 1370windows支持两种文件分隔符“/”和“\” 且使用“/”时 ... -
java中serializable是可以继承的
2010-05-16 21:58 5509import java.io.FileInputStream; ...
相关推荐
TM4C123系列是德州仪器(TI)推出的一款基于ARM Cortex-M4内核的微控制器,广泛应用于工业控制、嵌入式系统和电子设计大赛等场合。这个压缩包"TM4C123常用代码模板.zip"包含了针对TM4C123的源码示例和工程模板,对...
mpg123是一款开源的音频播放器,主要设计用于高效地播放MP3音频格式的文件。这个"mpg123 windows版本"是专为Windows操作系统编译的,为用户提供了在Windows环境下轻松享受音乐的工具。由于其轻量级的特性,mpg123在...
libmpg123是一个C++编写的库,专用于MP3音频的解码,它支持多种平台,包括Android。本篇文章将深入探讨libmpg123库在Android armeabi-v7a架构上的应用及实现音频解码的相关知识。 libmpg123库提供了高效且稳定的MP3...
### 74HC123 双可重触发单稳态触发器详解 #### 基本概述 74HC123是一款双通道可重触发的单稳态触发器,具备清除端功能,适用于各种电子电路设计中对脉冲宽度进行精确控制的需求。该器件有两种类型:CT54123/CT74123...
123云盘是一款提供高速下载体验的云存储服务,其主打特点是不限速,让用户能够享受流畅的上传和下载过程。在当前的互联网环境中,很多云盘服务由于版权和带宽成本的问题,对用户的下载速度进行了限制,而123云盘的...
《OpenDSS123节点源码解析:深入理解配电网潮流计算》 OpenDSS(Open Source Distribution System Simulator)是一款强大的电力系统分布式仿真软件,主要用于配电网的模拟与分析。在电力工程领域,OpenDSS被广泛...
标题中的"**url.hao123.aspjzy(1).rar_123.byios1:59898_www.yuecai.com123**"暗示这是一个关于hao123网站源代码的压缩文件,其中可能包含了一些ASP(Active Server Pages)文件和其他相关资源。"123.byios1:59898...
### 74LS123 双可重触发单稳态触发器详解 #### 基本概述 74LS123是一款双可重触发单稳态触发器芯片,带有清除端,常用于产生精确的脉冲信号。该芯片有两个独立的单稳态触发器单元,每个单元都可以通过外部电阻和...
libmpg123库是一款专为C++编程语言设计的高效音频解码库,主要用于处理MP3格式的音频文件。在Windows x64操作系统环境下,它提供了强大的功能,使开发者能够轻松地在64位系统上实现MP3音频的解码和播放。在本文中,...
【标题】"hao123网站源码"所涉及的知识点主要集中在网站开发、前端技术、网页设计以及用户体验方面。hao123作为中国知名的网址导航网站,它的源码解析对于我们理解互联网产品的构建、优化和运营具有重要的学习价值。...
74ls123引脚及功能 74ls123功能表 说明:1.外接电容接在 Cext(正)和 Rext/Cext(正)之间 2.为了改善脉冲宽度的精度和重复性,可在 Rext/Cext 和 Vcc 之间接外接电阻。 3.为了得到可变脉冲宽度,可在 ...
### 一、123资源最新采集接口概述 123资源最新采集接口主要涉及一系列用于不同内容管理系统(Content Management System,简称CMS)的数据抓取接口。这些接口能够帮助用户快速地获取视频资源和其他媒体内容,为用户...
【标题】:“hao123网站爬虫”是指使用Python编程语言开发的网络爬虫程序,目标是抓取hao123网址导航站的数据。这个案例旨在帮助学习者理解如何利用Python进行网页数据抓取,特别是针对像hao123这样具有大量链接的...
《123网盘在线解析源码:深入理解与应用》 在当今互联网时代,网盘已经成为用户存储、分享和访问文件的重要工具。123网盘在线解析源码是针对123网盘服务的一种技术实现,它允许用户通过浏览器直接访问和下载存储在...
### LV123标准知识点详解 #### 一、概述 LV123是戴姆勒股份公司(Daimler AG)发布的关于道路车辆高压组件电气特性和电气安全的标准。该标准详细规定了高压组件在设计、生产和测试过程中的具体要求与测试方法。LV...
123D Design 2.2.14资源介绍 123D Design 2.2.14是一款功能强大且免费使用的三维CAD设计软件,由知名软件公司Autodesk出品。这款软件以其易用性和丰富的功能深受用户喜爱,无论是初学者还是有一定经验的设计师,都...
FLUKE 123 示波表是一款专为电气工程师和维修技术人员设计的便携式测量工具,它结合了示波器和万用表的功能,能够帮助用户在各种环境中进行故障诊断和性能评估。这份“FLUKE 123 示波表 维修资料”包含了重要的技术...
在电子工程领域,74LS123是一种常用的可重触发集成单稳态触发器,它在各种定时和脉冲整形应用中发挥着关键作用。这个实验电路的Multisim源文件提供了对74LS123工作原理的直观理解和实践操作的机会。Multisim是一款...
在IT行业中,网络存储服务,如123网盘和cc网盘,为用户提供便捷的云存储和分享功能。"123网盘cc网盘快捷下载工具"是一款旨在优化和加速从这两个平台下载文件的软件。这类工具通常通过集成特定的下载技术,帮助用户绕...
123网盘解析PHP版本源码是一种非常实用的工具,可以方便地帮助用户在网页上直接解析出其它网站中的资源,并提供下载链接。当用户需要获取某些资源时,往往需要通过各种搜索引擎或者专业的资源网站进行查找,而且很多...