lock 锁class类对象和实例对象

java thread 线程中 的synchronized关键字 可以放到方法上,也可以修饰对象上
eg:

private synchronized void testSyncMethod() {
//当线程执行到此处时,它必须获得一个锁,此时锁定的对象是:调用此方法的对象a
}

private void testSyncMethod() {
synchronized(this){
//当线程执行到此处时,它必须获得一个锁,此时锁定的对象是:调用此方法的对象a
}
}


synchronized 可以修饰任何对象(int 等基本类型不在范围内),当然也包括类对象A.class
eg:

class A {
private static synchronized void testSyncMethod() {
//此时当前线程获得的锁是:A.class
}

private void testSyncMethod(){
synchronized(A.class){
//此时当前线程获得的锁是:A.class
}
}

}


既然A.class ,对象a 不是同一对象,即synchronized 修饰普通方法和静态方法是锁定了不同的对象。
下面的代码示例:


package com.horizon.thread.classLock;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* synchronized 修饰 static方法 锁定的是 class对象
* 即:synchronized (RunnableTest.class)
* @author wangxinchun
*
*/
public class SynchronizedStatic implements Runnable {

private static boolean flag = true;

private static synchronized void testSyncMethod() { // 注意static修饰的同步方法,监视器:SynchronizedStatic.class
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testSyncMethod:" + i);
}
}

private void testSyncBlock() {
synchronized (SynchronizedStatic.class) { // 显示使用获取class做为监视器.它与static synchronized method隐式获取class监视器一样.
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testSyncBlock:" + i);
}
}
}

public void run() {
// flag是static的变量.所以,不同的线程会执行不同的方法,只有这样才能看到不同的锁定效果.
if (flag) {
flag = false;
testSyncMethod();
} else {
flag = true;
testSyncBlock();
}
}

public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(2);
SynchronizedStatic rt = new SynchronizedStatic();
SynchronizedStatic rt1 = new SynchronizedStatic();
exec.execute(rt);
exec.execute(rt1);
exec.shutdown();
}
}

以上代码输出的结果是一个线程先执行,然后另外一个线程执行,输出是有序的:
testSyncMethod:0
testSyncMethod:1
testSyncMethod:2
testSyncMethod:3
testSyncMethod:4
testSyncMethod:5

如果去掉testSyncMethod 的静态方法,两个线程输出结果将是混乱在一起的(线程不再锁定同一对象):
testSyncMethod:0
testSyncBlock:0
testSyncMethod:1
testSyncBlock:1
testSyncMethod:2
testSyncBlock:2
testSyncMethod:3


下面这个案例是上个案例的翻版(输出将是乱序的)
请大家体会:

package com.horizon.thread.classLock;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
*
* synchronized (RunnableTest.class)
* 和 synchronized (this.getClass()) 是同等的
* @author wangxinchun
*
*/
public class SynchronizedStatic3 implements Runnable {

private static boolean flag = true;

private static synchronized void testSyncMethod() { // 注意static修改的同步方法,监视器=class
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testSyncMethod:" + i);
}
}

private void testNotSyncBlock() {
synchronized (this) { // 显示当前对象做为监视器
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testNotSyncBlock:" + i);
}
}
}

public void run() {
// flag是static的变量.所以,不同的线程会执行不同的方法,只有这样才能看到不同的锁定效果.(事实上此处是存在:race 条件)
if (flag) {
flag = false;
testSyncMethod();
} else {
flag = true;
testNotSyncBlock();
}
}

public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(2);
SynchronizedStatic3 rt = new SynchronizedStatic3();
SynchronizedStatic3 rt1 = new SynchronizedStatic3();
exec.execute(rt);
exec.execute(rt1);
exec.shutdown();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值