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使用的更多相关文章

  1. Java Synchronized Blocks

    From http://tutorials.jenkov.com/java-concurrency/synchronized.html By Jakob Jenkov   A Java synchro ...

  2. java synchronized(一)

    java synchronized主要用于控制线程同步,中间有很多小的细节,知识,这里我简单的整理一下,做个记录.主要用于方法和代码块的控制 先说说方法控制 模拟银行存款和取款,创建一个Account ...

  3. Java synchronized 详解

    Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ...

  4. Java Synchronized 关键字

    本文内容 Synchronized 关键字 示例 Synchronized 方法 内部锁(Intrinsic Locks)和 Synchronization 参考资料 下载 Demo Synchron ...

  5. Java synchronized 关键字详解

    Java synchronized 关键字详解 前置技能点 进程和线程的概念 线程创建方式 线程的状态状态转换 线程安全的概念 synchronized 关键字的几种用法 修饰非静态成员方法 sync ...

  6. Java synchronized对象级别与类级别的同步锁

    Java synchronized 关键字 可以将一个代码块或一个方法标记为同步代码块.同步代码块是指同一时间只能有一个线程执行的代码,并且执行该代码的线程持有同步锁.synchronized关键字可 ...

  7. java synchronized详解

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...

  8. Java synchronized

    1. 将synchronized加在方法上, 即可实现对此方法的同步 public synchronized void deposit(float amt) { float tmp = amount; ...

  9. Java synchronized指南

    在多线程程序中,同步修饰符用来控制对临界区代码的访问.其中一种方式是用synchronized关键字来保证代码的线程安全性.在Java中,synchronized修饰的代码块或方法不会被多个线程并发访 ...

随机推荐

  1. asp.net + Jquery 实现类似Gridview功能 (一)

    不知不觉2015年就过去一半了,由于过年前后公司人员陆续离职(这个...),项目忙不过来,从过年来上班就一直在忙,最近项目终于告一段落,开始步入正轨(不用天天赶项目了).所以最近才有时间写这个东西,可 ...

  2. Java 基础之 static 静态

    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何 ...

  3. PHP基础之 define() 函数

    定义和用法 define() 函数定义一个常量. 常量类似变量,不同之处在于: 在设定以后,常量的值无法更改 常量名不需要开头的美元符号 ($) 作用域不影响对常量的访问 常量值只能是字符串或数字 语 ...

  4. G - Reduced ID Numbers(第二季水)

    Description T. Chur teaches various groups of students at university U. Every U-student has a unique ...

  5. Linux程序设计 读笔3 文件操作

    一 linux文件结构 二 系统调用和设备驱动程序 三 库函数 四 底层文件访问 五 标准IO库 六 格式化输入输出 七 文件和目录的维护 八 扫描目录 九 错误处理 十

  6. C++程序设计实践指导1.2二维数组的操作运算改写要求实现

    改写要求1:改写为以单链表表示二维数组 #include <cstdlib> #include <iostream> using namespace std; struct L ...

  7. Java并发编程之闭锁简介

    闭锁相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关闭着的,没有任何线程可以通过,当到达结束状态时,这扇门才会打开并容许所有线程通过.它可以使一个或多个线程等待一组事件发生.闭锁状态包括一个计数器 ...

  8. 第一个XAML程序

    创建win8程序的默认Xaml文件是MainPage.Xaml文件,文件的内容如下所示: <Page x:Class="App1.MainPage" xmlns=" ...

  9. Android 上传库到Binary的操作

    第一次,按照网上教程配置需要的配置文件,上传成功 1.0版本. 以后更新的时候 输入 : install ,执行task 然后再输入:bintrayUpload ,执行task,看下面控制台输出信息, ...

  10. 关于采用MVC开发默认路由导致首页部分文件访问失效的临时解决方案

    最近开发中涉及了Mvc4的开发,其中的默认路由功能是很不错的东西,但是在实际应用中就出现了不少的问题.比如我们访问某网站http://www.abc.com,虽然路由会帮助自动转向Home/Index ...