关于synchronized
如果用synchronized修饰一个类成员方法A,那么就不会出现下面的情况:
同时多个线程访问这个类的A方法。
当然如果还有一个方法B,它没有被synchronized修饰,那么A方法与B方法是可以并行执行的。如下:
package thread;
public class SyncTest implements Runnable {
public synchronized void m1() throws Exception{
System.out.println("m1开始");
Thread.sleep(2000);
System.out.println("m1结束");
}
public void m2() throws Exception {
System.out.println("m2开始");
Thread.sleep(2000);
System.out.println("m2结束");
}
public void run() {
try {
m1();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
SyncTest tt = new SyncTest();
Thread t = new Thread(tt);
t.start();
Thread.sleep(1000); //保证先运行m1
tt.m2();
}
}
大家可以先猜一下运行结果
m1先运行打印出
m1开始
然后睡觉(2s后醒来)
过了大概1s
tt.m2()运行了
打印出
m2开始
再等一会
m1结束
m2结束
运行的结果也确实是
m1开始
m2开始
m1结束
m2结束
我们得出一个结论
成员函数A使用synchronized修饰,并不会影响没有使用synchronized修饰的方法B。
不过如果给m2也加上synchronized,会怎么呢?
结果如下
m1开始
m1结束
m2开始
m2结束
恩?答案是的。即使我们m1休眠的时间再长,m2也不会在m1执行结束之前启动。
因而我们得出结论
如果一个类中多个成员函数都用synchronized修饰,那么即使在多线程下,这些函数也不能同时被调用。
上面说的所以函数都是成员函数,如果把synchronized加到static方法上呢?
大家都知道,static的方法属于类方法,它属于这个Class(注意:这里的Class不是指Class的某个具体对象),那么static获取到的锁,就是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。而非static方法获取到的锁,就是当前调用这个方法的对象的锁了。所以,他们之间不会产生互斥。
看下面的例子
/**
* @author Jack Zhang
* @version vb1.0
* @Email virgoboy2004@163.com
* @Date 2012-5-20
*/
public class Test
{
public static synchronized void staticX() throws InterruptedException
{
for (int i = 0; i < 10; i++){
Thread.sleep(1000);
System.out.println("staticX.......................");
}
}
public synchronized void x() throws InterruptedException{
for (int i = 0; i < 10; i++){
Thread.sleep(1000);
System.out.println("x.......................");
}
}
public static void main(String[] args)
{
final Test test1 = new Test();
Thread thread = new Thread(new Runnable(){
public void run(){
try{
test1.x();
}catch (InterruptedException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "a");
Thread thread1 = new Thread(new Runnable(){
public void run(){
try{
Test.staticX();
} catch (InterruptedException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "b");
thread1.start();
thread.start();
}
}
结果是
staticX.......................
x.......................
x.......................
staticX.......................
staticX.......................
x.......................
x.......................
staticX.......................
x.......................
staticX.......................
staticX.......................
x.......................
x.......................
staticX.......................
x.......................
staticX.......................
x.......................
staticX.......................
x.......................
staticX.......................
一个锁加到的类上,另一个锁加到了对象上。是两回事。
那当我们想让所有这个类下面的对象都同步的时候,也就是让所有这个类下面的对象共用同一把锁的时候,我们如何办呢?
看代码:
/**
* @author Jack Zhang
* @version vb1.0
* @Email virgoboy2004@163.com
* @Date 2012-5-20
*/
public class Test
{
public final static Byte[] locks = new Byte[0];
public static void staticX() throws InterruptedException
{
synchronized (locks)
{
for (int i = 0; i < 10; i++)
{
Thread.sleep(1000);
System.out.println("staticX.......................");
}
}
}
public void x() throws InterruptedException
{
synchronized (locks)
{
for (int i = 0; i < 10; i++)
{
Thread.sleep(1000);
System.out.println("x.......................");
}
}
}
public static void main(String[] args)
{
final Test test1 = new Test();
final Test test2 = new Test();
Thread thread = new Thread(new Runnable()
{
public void run()
{
try
{
test1.x();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "a");
Thread thread1 = new Thread(new Runnable()
{
public void run()
{
try
{
Test.staticX();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "b");
thread1.start();
thread.start();
}
}
结果
staticX.......................
staticX.......................
staticX.......................
staticX.......................
staticX.......................
staticX.......................
staticX.......................
staticX.......................
staticX.......................
staticX.......................
x.......................
x.......................
x.......................
x.......................
x.......................
x.......................
x.......................
x.......................
x.......................
x.......................
关于synchronized(this)
我们知道在java中,this指的是调用这个方法的对象
如果我们写这样的锁synchronized(this) 会怎么样呢? 试一下不就知道了
public class Test
{
public final static Byte[] locks = new Byte[0];
public void staticX() throws InterruptedException
{
synchronized (this)
{
for (int i = 0; i < 10; i++)
{
Thread.sleep(1000);
System.out.println("staticX.......................");
}
}
}
public void x() throws InterruptedException
{
// synchronized (this)
{
for (int i = 0; i < 10; i++)
{
Thread.sleep(1000);
System.out.println("x.......................");
}
}
}
public static void main(String[] args)
{
final Test test1 = new Test();
// final Test test2 = new Test();
Thread thread = new Thread(new Runnable()
{
public void run()
{
try
{
test1.x();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "a");
Thread thread1 = new Thread(new Runnable()
{
public void run()
{
try
{
test1.staticX();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "b");
thread1.start();
thread.start();
}
}
此时x与staticx交替打印
这个大家能理解吗?x()方法没有任何锁,它自然能执行
如果我去掉x()方法里面的
// synchronized (this)
这行的注释呢?
结果是先连续打印10个staticx然后再打印10个x
感谢glt
参考资料http://blog.csdn.net/virgoboy2004/article/details/7585182
关于synchronized的更多相关文章
- java 多线程 Synchronized方法和方法块 synchronized(this)和synchronized(object)的理解
synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块. 1. synchronized 方法:通过在方法声明中加入 synchronized ...
- 单例模式中用volatile和synchronized来满足双重检查锁机制
背景:我们在实现单例模式的时候往往会忽略掉多线程的情况,就是写的代码在单线程的情况下是没问题的,但是一碰到多个线程的时候,由于代码没写好,就会引发很多问题,而且这些问题都是很隐蔽和很难排查的. 例子1 ...
- Thread 学习记录 <1> -- volatile和synchronized
恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1; ...
- synchronized使用说明
好久没有更新博客了,今天试着用简单的语言把synchronized的使用说清楚. synchronized是什么? synchronized是用来保证在多线程环境下代码同步执行的可重入的互斥锁.所谓互 ...
- 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition
img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...
- (转)Lock和synchronized比较详解
今天看了并发实践这本书的ReentantLock这章,感觉对ReentantLock还是不够熟悉,有许多疑问,所有在网上找了很多文章看了一下,总体说的不够详细,重点和焦点问题没有谈到,但这篇文章相当不 ...
- Synchronized同步性与可见性
Synchronized是具有同步性与可见性的,那么什么是同步性与可见性呢? (1)同步性:同步性就是一个事物要么一起成功,要么一起失败,可谓是有福同享有难同当,就像A有10000去银行转5000给身 ...
- 基于synchronized 或 ReadWriteLock实现 简单缓存机制
package cn.xxx.xxx; import java.util.HashMap; import java.util.Map; import java.util.concurrent.lock ...
- 【Java并发编程实战】-----synchronized
在我们的实际应用当中可能经常会遇到这样一个场景:多个线程读或者.写相同的数据,访问相同的文件等等.对于这种情况如果我们不加以控制,是非常容易导致错误的.在java中,为了解决这个问题,引入临界区概念. ...
- Lock、ReentrantLock、synchronized、ReentrantReadWriteLock使用
先来看一段代码,实现如下打印效果: 1 2 A 3 4 B 5 6 C 7 8 D 9 10 E 11 12 F 13 14 G 15 16 H 17 18 I 19 20 J 21 22 K 23 ...
随机推荐
- Python 3 函数自由变量的大坑
Python中函数是一个对象, 和整数,字符串等对象有很多相似之处,例如可以作为其他函数的参数或返回对象, Python中的函数还可以携带自由变量, 两者无疑极大增进了Python的表达力. 但是Py ...
- Python 通过继承实现标准对象的子类
idict是dict的子类,它的键值和属性是同步的,并且有强大的默认值机制. 例如,假设x是idict的一个实例,且x['a']['b']=12,则有x.a.b=12.反之亦然; 假设'c'不在x的键 ...
- PHP学习(3)—在HTML中嵌入PHP
我们以一个提交订单和显示订单信息的例子为学习PHP的开始.这个例子包含两个文件.一个提交订单的html文件:orderform.html,一个显示订单信息的php文件:processorder.php ...
- Linux动态频率调节系统CPUFreq之二:核心(core)架构与API
上一节中,我们大致地讲解了一下CPUFreq在用户空间的sysfs接口和它的几个重要的数据结构,同时也提到,CPUFreq子系统把一些公共的代码逻辑组织在一起,构成了CPUFreq的核心部分,这些公共 ...
- java虚拟机 jvm java堆 方法区 java栈
java堆是java应用程序最密切的内存空间.几乎所有的对象都存在堆中.java堆完全自动化管理,通过垃圾回收机制,垃圾对象会自动清理,不需要显式释放. 根据java垃圾回收机制的不同,java堆可能 ...
- Android上下文菜单ContentView详解
ContentView介绍 上下文菜单继承了android.view.Menu,因此我们可以像操作Options Menu那样给上下文菜单增加菜单项.上下文菜单与Options Menu最大的不同在于 ...
- (NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 用plist列表文件来表示游戏数据 因为在这个炸弹人游戏中有很多 ...
- Devstack: A copy of worked local.conf I'm sharing with you.
service_plugins = neutron.services.firewall.fwaas_plugin.FirewallPlugin [service_providers] service_ ...
- Hadoop的运行痕迹
http://www.cnblogs.com/forfuture1978/archive/2010/11/23/1884967.html 一篇讲的很好的 hadoop 基本运行环境配置信息
- 《java入门第一季》之HashSet存储自定义对象问题以及注意事项
上一篇http://blog.csdn.net/qq_32059827/article/details/51578158 写到存储字符串类型的时候出现了无序,而且这个无序不是随机那种无序,它是有一定存 ...