Java synchronized 用法
来源:互联网 发布:淘宝网店经营 编辑:程序博客网 时间:2024/06/03 02:37
1. synchronized 是JAVA关键字,可修饰方法和方法块。synchronized 的作用包括两方面:
1.1 多线程环境下的同步,多个线程互斥的访问同一个对象。
1.2 某个线程改变对象属性后,其他线程可及时获知该改变。
2. 在多线程环境中,同步方法被访问时,该类的非同步方法可以被访问;
非静态同步方法被访问时,同一实例的非静态方法不可被访问,静态同步方法可以被访问,非同一实例的非静态同步方法也可以被访问;
静态同步方法被访问时,该类的静态同步方法不可被访问,非静态同步方法可以被访问。
程序示例:
代码2-1
public class SynchronizedTest {public synchronized static void staticA() {int i = 0;while (i++ < 5) {System.out.println(Thread.currentThread().getName() + " staticA");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}public static void staticB() {synchronized (SynchronizedTest.class) {int i = 0;while (i++ < 5) {System.out.println(Thread.currentThread().getName()+ " staticB");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}}public synchronized void funA() {int i = 0;while (i++ < 5) {System.out.println(Thread.currentThread().getName() + " funA");try {Thread.sleep(400);} catch (InterruptedException e) {e.printStackTrace();}}}public void funB() {synchronized (this) {int i = 0;while (i++ < 5) {System.out.println(Thread.currentThread().getName() + " funB");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}}}
在代码2-1 中共包含四个方法,其中 staticA(), 和staticB () 方法以类(SynchronizedTest.class)为锁,fun A() 和funB() 以调用该方法的对象为锁。
下面以几个例子来说明 被 synchronized 关键字修饰的方法和关键字在多线程环境下的访问。
2.1 访问类的同步静态方法是,该类的其他静态同步方法不可被同时访问,非静态方法,同步非静态方法可以被同时访问。
代码2.1
<span style="white-space:pre"></span>public static void main(String[] args) {final SynchronizedTest ta = new SynchronizedTest();// final SynchronizedTest tb = new SynchronizedTest();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {ta.staticB();}}, "t1");Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {ta.staticA();}}, "t2");t1.start();t2.start();}代码2-2 的输出为:
t1 staticB
t1 staticB
t1 staticB
t1 staticB
t1 staticB
t2 staticA
t2 staticA
t2 staticA
t2 staticA
t2 staticA
staticA() 和staticB() 以类(SynchronizedTest.class)为锁,静态方法属于类方法,因此当访问某个同步静态方法被访问时,该类中其他的静态同步方法都不可访问。
代码2-3
public static void main(String[] args) {final SynchronizedTest ta = new SynchronizedTest();// final SynchronizedTest tb = new SynchronizedTest();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {ta.funA();}}, "t1");Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {ta.staticA();}}, "t2");t1.start();t2.start();}输出为:
t1 funA
t2 staticA
t1 funA
t2 staticA
t1 funA
t2 staticA
t1 funA
t2 staticA
t1 funA
t2 staticA
funA() 以调用它的对象ta为锁,staticA() 以类SynchronizedTest.class 为锁,在多线程环境下上述两个方法的访问互不影响,可以同时访问。
2.2 同步非静态方法被访问时,同一实例对象中的其他同步非静态方法不可以被访问。
代码2-3
public static void main(String[] args) {final SynchronizedTest ta = new SynchronizedTest();// final SynchronizedTest tb = new SynchronizedTest();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {ta.funA();}}, "t1");Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {ta.funB();}}, "t2");t1.start();t2.start();}输出:
t1 funA
t1 funA
t1 funA
t1 funA
t1 funA
t2 funB
t2 funB
t2 funB
t2 funB
t2 funB
funA() 和 funB() 均以对象ta为锁,因此在多线程环境下不能被同时访问。
2.3 同一个类的不同实例中,静态同步方法不可用被同时访问,非静态同步方法可以被同时访问。
public static void main(String[] args) {final SynchronizedTest ta = new SynchronizedTest();final SynchronizedTest tb = new SynchronizedTest();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {tb.funA();}}, "t1");Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {ta.funA();}}, "t2");t1.start();t2.start();}输出:
t2 funA
t1 funA
t2 funA
t1 funA
t2 funA
t1 funA
t1 funA
t2 funA
t1 funA
t2 funA
非静态同步方法以调用它的对象为锁,因此类的不同实例可以同时访问该方法。
静态同步方法以类为锁,因此即便是类的不同实例也不可以同时访问静态同步方法。
- java中synchronized用法
- java中synchronized用法
- java中synchronized用法
- java里面synchronized用法
- java中synchronized用法
- Java synchronized用法
- java中synchronized用法
- Java同步: synchronized用法
- java中synchronized用法
- java里面synchronized用法
- java里面synchronized用法
- java里面synchronized用法
- java中synchronized用法
- java synchronized用法小结
- Java synchronized用法搜集
- java中synchronized用法
- java中synchronized用法
- java中synchronized用法
- Linux程序设计(Linux shell编程十一)
- IOS持续的后台定位
- JAVA设计模式(二十)——备忘录模式
- Linux启动过程概述(X86)
- 实现UML 序列图 -- csdn MarkDown 第六篇 技术篇
- Java synchronized 用法
- 程序员练级攻略(CoolShell)
- GDUT 游戏王(状压DP)
- horizon is easy and complex
- UEditor
- OSI七层模型详解
- maven
- POJ 3744 Scout YYF I (概率dp+矩阵优化)
- Linux显示一行显示列总计