- 浏览: 7238426 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1546)
- 企业中间件 (236)
- 企业应用面临的问题 (236)
- 小布Oracle学习笔记汇总 (36)
- Spring 开发应用 (54)
- IBatis开发应用 (16)
- Oracle基础学习 (23)
- struts2.0 (41)
- JVM&ClassLoader&GC (16)
- JQuery的开发应用 (17)
- WebService的开发应用 (21)
- Java&Socket (44)
- 开源组件的应用 (254)
- 常用Javascript的开发应用 (28)
- J2EE开发技术指南 (163)
- EJB3开发应用 (11)
- GIS&Mobile&MAP (36)
- SWT-GEF-RCP (52)
- 算法&数据结构 (6)
- Apache开源组件研究 (62)
- Hibernate 学习应用 (57)
- java并发编程 (59)
- MySQL&Mongodb&MS/SQL (15)
- Oracle数据库实验室 (55)
- 搜索引擎的开发应用 (34)
- 软件工程师笔试经典 (14)
- 其他杂项 (10)
- AndroidPn& MQTT&C2DM&推技术 (29)
- ActiveMQ学习和研究 (38)
- Google技术应用开发和API分析 (11)
- flex的学习总结 (59)
- 项目中一点总结 (20)
- java疑惑 java面向对象编程 (28)
- Android 开发学习 (133)
- linux和UNIX的总结 (37)
- Titanium学习总结 (20)
- JQueryMobile学习总结 (34)
- Phonegap学习总结 (32)
- HTML5学习总结 (41)
- JeeCMS研究和理解分析 (9)
最新评论
-
lgh1992314:
[u][i][b][flash=200,200][url][i ...
看看mybatis 源代码 -
尼古拉斯.fwp:
图片根本就不出来好吧。。。。。。
Android文件图片上传的详细讲解(一)HTTP multipart/form-data 上传报文格式实现手机端上传 -
ln94223:
第一个应该用排它网关吧 怎么是并行网关, 并行网关是所有exe ...
工作流Activiti的学习总结(八)Activiti自动执行的应用 -
ZY199266:
获取不到任何消息信息,请问这是什么原因呢?
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息 -
xiaoyao霄:
DestinationSourceMonitor 报错 应该导 ...
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息
进行多线程编程,同步控制是非常重要的,而同步控制就涉及到了锁。
对代码进行同步控制我们可以选择同步方法,也可以选择同步块,这两种方式各有优缺点,至于具体选择什么方式,就见仁见智了,同步块不仅可以更加精确的控制对象锁,也就是控制锁的作用域,何谓锁的作用域?锁的作用域就是从锁被获取到其被释放的时间。而且可以选择要获取哪个对象的对象锁。但是如果在使用同步块机制时,如果使用过多的锁也会容易引起死锁问题,同时获取和释放所也有代价,而同步方法,它们所拥有的锁就是该方法所属的类的对象锁,换句话说,也就是this对象,而且锁的作用域也是整个方法,这可能导致其锁的作用域可能太大,也有可能引起死锁,同时因为可能包含了不需要进行同步的代码块在内,也会降低程序的运行效率。而不管是同步方法还是同步块,我们都不应该在他们的代码块内包含无限循环,如果代码内部要是有了无限循环,那么这个同步方法或者同步块在获取锁以后因为代码会一直不停的循环着运行下去,也就没有机会释放它所获取的锁,而其它等待这把锁的线程就永远无法获取这把锁,这就造成了一种死锁现象。
详细解说一下同步方法的锁,同步方法分为静态同步方法与非静态同步方法。
所有的非静态同步方法用的都是同一把锁——实例对象本身,也就是说如果一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁,可是别的实例对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁,所以毋须等待该实例对象已获取锁的非静态同步方法释放锁就可以获取他们自己的锁。
而所有的静态同步方法用的也是同一把锁——类对象本身,这两把锁是两个不同的对象,所以静态同步方法与非静态同步方法之间是不会有竞态条件的。但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态同步方法之间,还是不同的实例对象的静态同步方法之间,只要它们同一个类的实例对象!
而对于同步块,由于其锁是可以选择的,所以只有使用同一把锁的同步块之间才有着竞态条件,这就得具体情况具体分析了,但这里有个需要注意的地方,同步块的锁是可以选择的,但是不是可以任意选择的!!!!这里必须要注意一个物理对象和一个引用对象的实例变量之间的区别!使用一个引用对象的实例变量作为锁并不是一个好的选择,因为同步块在执行过程中可能会改变它的值,其中就包括将其设置为null,而对一个null对象加锁会产生异常,并且对不同的对象加锁也违背了同步的初衷!这看起来是很清楚的,但是一个经常发生的错误就是选用了错误的锁对象,因此必须注意:同步是基于实际对象而不是对象引用的!多个变量可以引用同一个对象,变量也可以改变其值从而指向其他的对象,因此,当选择一个对象锁时,我们要根据实际对象而不是其引用来考虑!作为一个原则,不要选择一个可能会在锁的作用域中改变值的实例变量作为锁对象!!!!
Java线程:线程的同步与锁
6)、线程睡眠时,它所持的任何锁都不会释放。
private int x = 100;
public int getX() {
return x;
}
public int fix(int y) {
x = x - y;
return x;
}
}
private Foo foo = new Foo();
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread ta = new Thread(r, "Thread-A");
Thread tb = new Thread(r, "Thread-B");
ta.start();
tb.start();
}
public void run() {
for (int i = 0; i < 3; i++) {
this.fix(30);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : 当前foo对象的x值= " + foo.getX());
}
}
public int fix(int y) {
return foo.fix(y);
}
}
Thread-B : 当前foo对象的x值= 40
Thread-B : 当前foo对象的x值= -20
Thread-A : 当前foo对象的x值= -50
Thread-A : 当前foo对象的x值= -80
Thread-B : 当前foo对象的x值= -80
Process finished with exit code 0
synchronized (this) {
x = x - y;
}
return x;
}
return x++;
}
synchronized (this) {
return x;
}
}
public static int setName(String name){
synchronized(Xxx.class){
Xxx.name = name;
}
}
private List nameList = Collections.synchronizedList(new LinkedList());
public void add(String name) {
nameList.add(name);
}
public String removeFirst() {
if (nameList.size() > 0) {
return (String) nameList.remove(0);
} else {
return null;
}
}
}
public static void main(String[] args) {
final NameList nl = new NameList();
nl.add("aaa");
class NameDropper extends Thread{
public void run(){
String name = nl.removeFirst();
System.out.println(name);
}
}
Thread t1 = new NameDropper();
Thread t2 = new NameDropper();
t1.start();
t2.start();
}
}
private List nameList = Collections.synchronizedList(new LinkedList());
public synchronized void add(String name) {
nameList.add(name);
}
public synchronized String removeFirst() {
if (nameList.size() > 0) {
return (String) nameList.remove(0);
} else {
return null;
}
}
}
private static class Resource {
public int value;
}
private Resource resourceA = new Resource();
private Resource resourceB = new Resource();
public int read() {
synchronized (resourceA) {
synchronized (resourceB) {
return resourceB.value + resourceA.value;
}
}
}
public void write(int a, int b) {
synchronized (resourceB) {
synchronized (resourceA) {
resourceA.value = a;
resourceB.value = b;
}
}
}
}
package com.etrip.concurrent.executor; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * 非静态同步方法,静态同步方法,同步语句块的使用 * * * 进行多线程编程,同步控制是非常重要的,而同步控制就涉及到了锁。 对代码进行同步控制我们可以选择同步方法,也可以选择同步块,这两种方式各有优缺点,至于具体选择什么方式,就见仁见智了,同步块不仅可以更加精确的控制对象锁,也就是控制锁的作用域,何谓锁的作用域?锁的作用域就是从锁被获取到其被释放的时间。而且可以选择要获取哪个对象的对象锁。但是如果在使用同步块机制时,如果使用过多的锁也会容易引起死锁问题,同时获取和释放所也有代价,而同步方法,它们所拥有的锁就是该方法所属的类的对象锁,换句话说,也就是this对象,而且锁的作用域也是整个方法,这可能导致其锁的作用域可能太大,也有可能引起死锁,同时因为可能包含了不需要进行同步的代码块在内,也会降低程序的运行效率。而不管是同步方法还是同步块,我们都不应该在他们的代码块内包含无限循环,如果代码内部要是有了无限循环,那么这个同步方法或者同步块在获取锁以后因为代码会一直不停的循环着运行下去,也就没有机会释放它所获取的锁,而其它等待这把锁的线程就永远无法获取这把锁,这就造成了一种死锁现象。 * * @author longgangbai */ public class StaticInstanceLock { private int count; private static StaticInstanceLock instance=null; private StaticInstanceLock(){ } /** * 静态方法的锁 * * @return */ public static synchronized StaticInstanceLock getInstance(){ if(instance==null){ instance=new StaticInstanceLock(); } return instance; } /** * 非静态方法的锁 * @return */ public synchronized int getCount(){ return count; } public synchronized void setCount(int count){ this.count=count; } /** * 同步语句块的使用 * */ public void synmethod(){ //HashMap为非安全性Map HashMap<String,String> hashmap = new HashMap<String,String>(); hashmap.put("ZH","中国"); hashmap.put("EN","英国"); hashmap.put("AM","美国"); hashmap.put("FR","法国"); //创建一个同步的对象Map Map<String,String> m = Collections.synchronizedMap(hashmap); Set<String> s = m.keySet(); // Needn't be in synchronized block //这里同步的对象均为需要使用同步的对象如Map而非Set synchronized(m) { // Synchronizing on m, not s! Iterator<String> i = s.iterator(); // Must be in synchronized block while (i.hasNext()){ foo(i.next()); } } } public void foo(String entry){ System.out.println("StaticInstanceLock ="+entry); } public static void main(String[] args) { StaticInstanceLock instance=StaticInstanceLock.getInstance(); instance.setCount(7); int count = instance.getCount(); instance.synmethod(); } }
发表评论
-
【转】Coherence Event Processing by using Map Trigger Feature
2013-06-25 14:02 2024This article shows how to proc ... -
【转】Distributed Data Management in Oracle Coherence
2013-06-25 13:55 1686This article shows how to prov ... -
【转】How to distribute Spring Beans by using Coherence
2013-06-21 17:24 1744转载自: http://www.onli ... -
关于H2使用的那些事
2012-12-14 16:40 27060在项目中采用H2作为工 ... -
【转】ConcurrentHashMap之实现细节
2012-12-10 14:32 1705Conc ... -
【转】Java并发编程J.U.C之Condition
2012-12-10 13:14 1827转载自http://www.golde ... -
【转】Java并发编程J.U.C之锁的获取与释放
2012-12-10 13:07 1555转载自 http://www.g ... -
【转】JUC 基础内容概述
2012-12-10 13:01 1981Concurrent Programming in Jav ... -
【转】Java并发编程之ConcurrentHashMap
2012-12-10 12:56 1710ConcurrentHashMap Conc ... -
【转】单例模式完全解析
2012-12-07 12:58 1639本文将探讨单例模式的各种情况,并给出相应的建议。 单例模式应该 ... -
【转】JAVA并发容器代码随读
2012-12-06 15:29 2894转载自 http://rdc.taobao.c ... -
【转】Spring 事务管理高级应用难点剖析:
2012-12-04 16:29 2163转载自 http://www.ibm.com/deve ... -
【转】Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式
2012-12-04 15:11 4403转载自 http://downpour.ite ... -
Hibernate延迟加载和OpenSessionInView
2012-12-03 17:13 3111ThreadLocal& ... -
关于ThreadLocal分析和总结
2012-12-03 15:56 1793什么是ThreadLocal? ... -
【转】java线程阻塞中断和LockSupport的常见问题
2012-12-03 13:30 1729转载自 http://www.iteye ... -
java 中 ReentrantReadWriteLock的读锁和写锁的使用
2012-11-30 17:14 10362jdk文档中关于Reentr ... -
java 多线程中Semaphore信号量
2012-11-30 15:39 3698Semaphore信号量: 可以维护当前 ... -
Java 文件锁的使用
2012-11-30 13:21 4372多线程-内部锁、重进入 多线程 ... -
【转】线程安全与锁优化
2012-11-29 16:17 1794转载自http://xussen.iteye.com/blo ...
相关推荐
11.3.12 静态方法何以为“静态” 314 11.4 变量的修饰符 316 11.4.1 变量方法皆成员 317 11.4.2 变量的访问控制符 317 11.4.3 使用private修饰类的成员变量 318 11.4.4 使用private,然后呢? 320 11.4.5 变量...
11.3.12 静态方法何以为“静态” 314 11.4 变量的修饰符 316 11.4.1 变量方法皆成员 317 11.4.2 变量的访问控制符 317 11.4.3 使用private修饰类的成员变量 318 11.4.4 使用private,然后呢? 320 11.4.5 变量...
8.1.1 非静态成员内部类203 8.1.2 局部内部类206 8.1.3 静态内部类209 8.1.4 匿名内部类211 8.2 对象包装器213 8.3 装箱和拆箱216 8.4 本章习题218 第9章 9.1 String类220 9.1.1 字符串常量221 9.1.2 字符串对象操作...
多线程,用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 59.使用socket建立客户端与服务器的通信的过程 60.JAVA语言国际化应用,Locale类,Unicode 61.描述反射机制的作用 62.如何读写一个...
java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 6、说出Servlet的生命周期,并说出Servlet和CGI的区别。 Servlet被服务器实例化后,容器运行其init方法,...
34、是否可以从一个static 方法内部发出对非static 方法的调用? 11 35、写clone()方法时,通常都有一行代码,是什么? 11 36、GC 是什么? 为什么要有GC? 11 37、垃圾回收的优点和原理。并考虑2 种回收机制。 11 38...
13、是否可以从一个static方法内部发出对非static方法的调用? 12 14、Integer与int的区别 13 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 13 16、下面的代码有什么不妥之处? 13 17、请说出作用域...
13、是否可以从一个static方法内部发出对非static方法的调用? 12 14、Integer与int的区别 13 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 13 16、下面的代码有什么不妥之处? 13 17、请说出作用域...
java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 9、说出Servlet的生命周期,并说出Servlet和CGI的区别。 Servlet被服务器实例化后,容器运行其init方法...
13、是否可以从一个static方法内部发出对非static方法的调用? 12 14、Integer与int的区别 13 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 13 16、下面的代码有什么不妥之处? 13 17、请说出作用域...
13、是否可以从一个static方法内部发出对非static方法的调用? 14、Integer与int的区别 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 16、下面的代码有什么不妥之处? 17、请说出作用域public,...
13、是否可以从一个static方法内部发出对非static方法的调用? 12 14、Integer与int的区别 13 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 13 16、下面的代码有什么不妥之处? 13 17、请说出作用域...
13、是否可以从一个static方法内部发出对非static方法的调用? 12 14、Integer与int的区别 13 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 13 16、下面的代码有什么不妥之处? 13 17、请说出作用域...
13、是否可以从一个static方法内部发出对非static方法的调用? 13 14、Integer与int的区别 13 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 14 16、下面的代码有什么不妥之处? 14 17、请说出作用域...
61. 是否可以从一个static方法内部发出对非static方法的调用? 14 62. 写clone()方法时,通常都有一行代码,是什么? 14 63. 在JAVA中,如何跳出当前的多重嵌套循环? 14 64. List、Map、Set三个接口,存取元素时,各有什么...
3、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 56 4、线程的基本概念 57 5、什么是多线程 57 6、程序、进程、线程之间的关系 57 7、创建线程有几种方式,分别是什么? ...
13、是否可以从一个static方法内部发出对非static方法的调用? 12 14、Integer与int的区别 13 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 13 16、下面的代码有什么不妥之处? 13 17、请说出作用域...