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修饰的代码块或方法不会被多个线程并发访 ...
随机推荐
- 记录ASP.NET页面表单初始状态(主要是为了前台可以根据这个判断页面是否变动了)
把页面表单状态记录到HiddenField中. 这里只提供后台代码, 前台逻辑根据需求自由定义. 存放值的ViewState: protected Dictionary<string, stri ...
- android实现透明和半透明效果
从透明到半透明时一个值的变化过程. #00000000(全透明)——#e0000000(半透明) 如果觉得半透明的效果太暗淡.可以设置成#60000000,#80000000,#a0000000等等
- android第三方分享之友盟社会化组件
前言 现在几乎所有的app都带有分享功能,第一为了更好地推广自己的产品,第二作为使用者也能及时的把自己觉得好的文章,话题,app分享到社交平台供大家一起学习和使用.开发中虽然android系统自带分享 ...
- android 5.0新特性CardView教程
CardView 是android5.0新加入的特性,大家先别着急,由于谷歌出了cardview的兼容包,也就是android.support.v7.widget.CardView包,所以在5.0以下 ...
- ref 关键字out关键字
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- Foundation--NSString+NSMutableString
NSString 字符串创建: 1.NSString *strr = @"0123456789"; 2.NSString *str = [NSString stringWithSt ...
- Lambda 表达式中的变量范围
delegate bool D(); delegate bool D2(int i); class Test { D del; D2 del2; public void TestMethod(int ...
- linux下C++ STL hash_map的使用以及使用char *型变量作为Key值的一大“坑”
计算机编程中经常会用到hash表,而在C++中,使用STL编程更是少不了的.本文将介绍STL中hash_map的使用.在hash_map中使用自定义类型作为key值的方法以及在使用char *类型作为 ...
- HTML5 canvas 在线画笔绘图工具(四)
HTML5画图命令 图形的绘制是由TDrawHandler与TCommand 协同工作完成. TDrawHandler需要完成以下工作 1.聚集类用于管理绘图的命令 TCommand 2.管理鼠标事件 ...
- SQL Server中in与exist效率比较
in和exists in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询. 一直以来认为exists比in效率高的说法是不准确的. 如果查询的两 ...