java synchronized使用
java synchronized
基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案。这意味着在给定时刻只允许一个任务访问该资源。这个一般通过在代码上加一条锁语句实现,因为锁语句产生一种互斥排斥的效果,这种机制常常被称为互斥机制。
线程是簇拥在共享资源门前,并不是排队进入,可以通过yield()和setPriority()来给线程调度提供建议,但这些建议未必会有多大的效果。这取决与你的具体平台和vm的实现:)--//from 《think in java》
java中提供关键字synchronized,为防止资源冲突提供内置支持。当他用来修饰一个方法或者代码块的时候,能够保证在同一时间最多只有一个线程访问执行该方法或者代码块;关于synchronized用于方法,用于代码块,用于静态方法可以参考博客Java中Synchronized的用法
sychronized(this)的理解:
this它指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。=.= 那个拿到了P1对象锁的线程,才可以调用P1的同步方法,而对P2而言,P1这个锁与它毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造成数据混乱 :) 使用三个实例加强理解:
示例一:
public class Thread1 implements Runnable {
public void run() {
synchronized(this) { //枷锁
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread ta = new Thread(t1, "A");
Thread tb = new Thread(t1, "B"); //A线程先执行完毕,再执行B线程
ta.start();
tb.start();
}
}
结果:
A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4
示例二:
public class Thread2 {
public void m4t1() {
synchronized (this) {//枷锁1
int i = 5;
while (i-- > 0) {
System.out
.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
} public void m4t2() {
synchronized (this) {//枷锁2
int i = 5;
while (i-- > 0) {
System.out
.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(300);//休眠短一些
} catch (InterruptedException ie) {
}
}
}
} public static void main(String[] args) {
final Thread2 myt2 = new Thread2();
Thread t1 = new Thread(new Runnable() {
public void run() {
myt2.m4t1();//A线程只调用了枷锁的m4t1(),B线程调用枷锁的m4t2(),仍然需要等待A执行完毕
}
}, "A");
Thread t2 = new Thread(new Runnable() {
public void run() {
myt2.m4t2();
}
}, "B");
t1.start();
t2.start();
}
}
结果:
A : 4
A : 3
A : 2
A : 1
A : 0
B : 4
B : 3
B : 2
B : 1
B : 0
也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
示例三:
public class Thread3 {
public void m4t1() {
synchronized (this) {//枷锁
int i = 5;
while (i-- > 0) {
System.out
.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
} public void m4t2() {int i = 5;//不枷锁
while (i-- > 0) {
System.out
.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(300);
} catch (InterruptedException ie) {
}
}
} public static void main(String[] args) {
final Thread3 myt3 = new Thread3();
Thread t1 = new Thread(new Runnable() {
public void run() {
myt3.m4t1(); //
}
}, "A");
Thread t2 = new Thread(new Runnable() {
public void run() {
myt3.m4t2();
}
}, "B");
t1.start();
t2.start();
}
}
结果: (具有不确定性)
A : 4
B : 4
B : 3
A : 3
B : 2
B : 1
A : 2
B : 0
A : 1
A : 0
当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
总结:所有的对象都有单一的锁(也成为监视器)。当在对象上调用任意的synchronized方法的时候,此对象都被加锁,这时调用该对象上其他的synchronized方法只有等待前一个方法调用完毕并释放所之后才能调用。
注意:在使用并发的时候,将域设置为private时非常重要的。否则,synchronized关键字就不能防止其他任务直接访问域,这样就会产生冲突。
one more thing:
一个任务可以多次获得对象的锁,如果一个方法在同一对象上调用了第二个方法,后者又调用了同一对象上的另一个方法,就会发生这样的情况。JVM负责跟踪对象被加锁的次数。如果一个对象被完全解锁,其计数变为0.每当任务离开一个synchronized方法,计数递减,当计数为0,锁被完全释放,此时别的任务就可以使用此资源:)
针对每一个类,也有一个锁(作为类的class对象的一部分),所以synchronized static方法可以在类的范围类防止对static数据的并发访问。
java synchronized使用的更多相关文章
- Java Synchronized Blocks
From http://tutorials.jenkov.com/java-concurrency/synchronized.html By Jakob Jenkov A Java synchro ...
- java synchronized(一)
java synchronized主要用于控制线程同步,中间有很多小的细节,知识,这里我简单的整理一下,做个记录.主要用于方法和代码块的控制 先说说方法控制 模拟银行存款和取款,创建一个Account ...
- Java synchronized 详解
Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ...
- Java Synchronized 关键字
本文内容 Synchronized 关键字 示例 Synchronized 方法 内部锁(Intrinsic Locks)和 Synchronization 参考资料 下载 Demo Synchron ...
- Java synchronized 关键字详解
Java synchronized 关键字详解 前置技能点 进程和线程的概念 线程创建方式 线程的状态状态转换 线程安全的概念 synchronized 关键字的几种用法 修饰非静态成员方法 sync ...
- Java synchronized对象级别与类级别的同步锁
Java synchronized 关键字 可以将一个代码块或一个方法标记为同步代码块.同步代码块是指同一时间只能有一个线程执行的代码,并且执行该代码的线程持有同步锁.synchronized关键字可 ...
- java synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
- Java synchronized
1. 将synchronized加在方法上, 即可实现对此方法的同步 public synchronized void deposit(float amt) { float tmp = amount; ...
- Java synchronized指南
在多线程程序中,同步修饰符用来控制对临界区代码的访问.其中一种方式是用synchronized关键字来保证代码的线程安全性.在Java中,synchronized修饰的代码块或方法不会被多个线程并发访 ...
随机推荐
- js判断是否为ie的方法
原文:http://blog.sina.com.cn/s/blog_7bbe4a850100v95z.html 下面第三种亲测可用 第一种: if(window.addEventListener){ ...
- C#同步数据库的数据到Neo4J
数据组件采用https://github.com/Readify/Neo4jClient 在nuget里面有 需要注意的是 以下是示例代码: using System;using System.Col ...
- php中的短标签 太坑人了
今天配置了一个php页面去修改svn密码问题,结果调了半天,最后在Windows和 Linux的运行现象是不一样,运行结果更不一样了,关键是完全一模一样的代码. 最后发现是短标签引起的,Windows ...
- C++ primer学习记录(个人猜想未测试版本)
学习版本:第五版. 本博文主要记录个人曾经并不知晓知识细节. 因为linux下的编译环境还未进行学习.所以实际代码测试将在今后完成. 红色:需确认. 蓝色:重点. 1)const对象设定为仅在文件内有 ...
- Shell学习之Shift的用法
位置参数可以用shift命令左移.比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1.$2.$3丢弃,$0不移动.不带参数的shift命令相当于shift 1 ...
- oracle使用口令文件验证和os验证
一.Oracle安装之后默认情况下是启用了OS认证的,这里提到的os认证是指服务器端os认证.OS认证的意思把登录数据库的用户和口令校验放在了操作系统一级.如果以安装Oracle时的用户登录OS,那么 ...
- Oracle数据库中如何选择合适的索引类型 .
索引就好象一本字典的目录.凭借字典的目录,我们可以非常迅速的找到我们所需要的条目.数据库也是如此.凭借Oracle数据库的索引,相关语句可以迅速的定位记录的位置,而不必去定位整个表. 虽然说,在表中是 ...
- Window10安装TestLink,以及登录mysql数据库的错误处理
步骤一: 需要安装apache和mysql,但是我们这里仅仅是使用testlink,不关注其他,所以使用Vertrigoserv进行傻瓜式安装,安装完后,下载testlink解压,将解压后的文件放入D ...
- Mybatis.net与MVC入门配置及联合查询动态SQL拼接和简单事务
第一次学习Mybatis.net,在博客园也找到好多资料,但是在配置成功之后也遇到了一些问题,尤其是在动态SQl拼接时候,这里把遇到的问题还有自己写的一个Demo贴出来,希望能帮到新手,有不适合的地方 ...
- 转的git
原文链接:http://blog.csdn.NET/dengjianqiang2011/article/details/9260435 如果输入$ Git remote add origin git@ ...