1、synchronized关键字的作用域有二种:
1) 是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法
(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不 能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。
也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
2) 是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。
它可以对类的所有对象实例起作用。
2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。
用法是: synchronized(this){/*区块*/},它的作用域是当前对象;
3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},
而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;
--------------------------
synchronized 方法控制对类成员变量的访问:
- 每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。
- 这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
- 在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。
-------------------------------
我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 synchronized 块。
通过 synchronized关键字来声明synchronized 块。语法如下:
synchronized(syncObject) { //允许访问控制的代码 }
synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机制同前所述。
由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。
- 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
- 二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
- 三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。(对synchronized方法呢?)
- 四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
- 五、以上规则对其它对象锁同样适用.
当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。 另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
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); } } } public static void main(String[] args) { Thread1 t1 = new Thread1(); Thread ta = new Thread(t1, "A"); Thread tb = new Thread(t1, "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
--------------------------------------------------------------------------------
然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非
synchronized(this)同步代码块。
public class Thread2 { 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(500); } 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(); } }, "t1"); Thread t2 = new Thread(new Runnable() { public void run() { myt2.m4t2(); } }, "t2"); t1.start(); t2.start(); } }
t1 : 4
t2 : 4
t1 : 3
t2 : 3
t1 : 2
t2 : 2
t1 : 1
t2 : 1
t1 : 0
t2 : 0
----------------------------------------------
当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它
synchronized(this)同步代码块的访问将被阻塞。
//修改Thread2.m4t2()方法: public void m4t2() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
结果:
t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0
第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时, 它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
http://www.blogjava.net/jialisoftwo/archive/2012/10/26/390272.html
相关推荐
synchronized关键字我们大家都知道是线程同步关键字.总结一下日常的使用方法,还有一个坑.
主要介绍了Java多线程编程中易混淆的3个关键字总结,本文总结了、volatile、ThreadLocal、synchronized等3个关键字,对这几个容易混淆概念的关键字分别做了讲解,需要的朋友可以参考下
一些关键且实用的Java开发技巧: 基础语法与规范: 始终使用public class并遵循...使用synchronized关键字或Lock接口进行同步控制。 利用ExecutorService进行多线程任务管理。 注意volatile关键字的使用,确保多线程
Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,相比于synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。但是volatile 变量的同步性...
java高并发开发必须要会的知识,锁知识,关键字 Synchronized_锁升级知识点总结,面试常用
看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一....1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 ...1)ReentrantLock和synchronized关键字的区别 41
采用synchronized关键字、volatile、ReebtrabtLook类与阻塞列队LinkedBlockingQueue,完成主线程与子线程的同步,要求子线程先执行,在主线程中使用Thread类创建一个子线程,主线程创建后进入阻塞状态,直到子线程...
1.Day01-jdk8新特性 ---【课时1】01-JDK8简介.mp4 ---【课时2】02-JDK8接口新特性应用.mp4 ---【课时3】03-JDK8中lambda...---【课时5】05-synchronized关键字分析.mp4 ---【课时6】06-volatile关键字应用分析.mp4 -
1.2 synchronized关键字 可以在任意对象及方法上加锁,而加锁的这段代码称为互斥区或临界值 什么是互斥区? 就是多个处理器都可以访问一块共享的内存,但为了结果的正确性,一个处理器必须完成访问这块内存和某些...
500-interview-question-for-programmers概述本 Repository 用于记录个人平时面试和学习时碰到的一些有价值的问题,所有问题均为我真实碰到过且思考过(大部分附具体... 线程安全 (使用 synchronized 关键字实现)S
java8 源码 Java SE 的代码与笔记 [ReadMe部分没有代码,代码都在项目文件中] ...哪个线程先执行带有synchronized关键字的方法,哪个对象就拥有该方法所属对象的锁Lock 当A线程调用anyObject对象加入syn
synchronized (关键字) 同步(锁) ['siŋkrәnaiz] Thread [java] 线程 [θred] throw (关键字) throws (关键字) [θrәu] 抛出(异常) transient (关键字) 瞬变;临时的['trænziәnt]'(可序列化) valid 正确的,...
private synchronized void inc(){ j++; System.out.println(Thread.currentThread().getName()+"-inc:"+j); } private synchronized void dec(){ j--; System.out.println(Thread.currentThread().getName()+"-...
一名JAVA程序员,将自己的编程学习之路做以总结并进行分享。内容包括但不限于数据结构、算法、数据库、操作系统、计算机网络等多方面。 博文: 目前先暂列目录,内容在逐渐增加中 JAVA 关键字 void byte int long ...
关键字 void byte int long char short float double String StringBuffer StringBuilder Array Collection Collections List ArrayList LinkedList Vector Set HashMap TreeMap LinkedHashMap ConcerrentHashMap ...
11.2.5 总结:类的修饰符 297 11.3 方法的修饰符 297 11.3.1 方法的访问控制符 298 11.3.2 public:没有限制的修饰符 299 11.3.3 protected:仅对子类和同包的类可见 300 11.3.4 默认控制符:仅在本包中可见 ...
11.2.5 总结:类的修饰符 297 11.3 方法的修饰符 297 11.3.1 方法的访问控制符 298 11.3.2 public:没有限制的修饰符 299 11.3.3 protected:仅对子类和同包的类可见 300 11.3.4 默认控制符:仅在本包中可见 ...
│ 高并发编程第一阶段19讲、结合jconsole,jstack以及汇编指令认识synchronized关键字.mp4 │ 高并发编程第一阶段20讲、同步代码块以及同步方法之间的区别和关系.mp4 │ 高并发编程第一阶段21讲、通过实验分析...
│ 高并发编程第一阶段19讲、结合jconsole,jstack以及汇编指令认识synchronized关键字.mp4 │ 高并发编程第一阶段20讲、同步代码块以及同步方法之间的区别和关系.mp4 │ 高并发编程第一阶段21讲、通过实验分析...
【基础】transient关键字 15 【基础】访问修饰符区别 15 【基础】java基本数据类型(四类八种) 15 Java自动类型转换 16 数据类型自动提升(注意以下讨论的是二元操作符) 16 【基础】switch支持的类型 17 【基础】...