当前位置:   article > 正文

java 对象锁和类锁_synchronized对象锁和类锁.

调用类锁

对象锁概念Java的所有对象都含有1个互斥锁,这个锁由JVM自动获取和释放。线程进入synchronized方法的时候获取该对象的锁,当然如果已经有线程获取了这个对象的锁,那么当前线程会等待,synchronized方法正常返回或者抛异常而终止,JVM会自动释放对象锁。这里也体现了用synchronized来加锁的一个好处,方法抛异常的时候,锁仍然可以由JVM来自动释放。// 对象锁:形式1(方法锁)

public synchronized void Method1() {

System.out.println("我是对象锁也是方法锁");

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

// 对象锁:形式2(代码块形式)

public void Method2() {

synchronized (this) {

System.out.println("我是对象锁");

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

类锁的概念由于一个class不论被实例化多少次,其中的静态方法和静态变量在内存中都只有一份。所以,一旦一个静态的方法被申明为synchronized。此类所有的实例化对象在调用此方法,共用同一把锁,我们称之为类锁。public synchronized static void Method3() {

System.out.println("我是类锁");

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

代码演示类锁和对象锁下面这段代码是两个类锁和一个对象锁,拿到锁后,睡1秒钟。// 类锁A

public synchronized static void classLockA() {

System.out.println("name = " + Thread.currentThread().getName() + ", begain");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("name = " + Thread.currentThread().getName() + ", end");

}

// 类锁B

public synchronized static void classLockB() {

System.out.println("name = " + Thread.currentThread().getName() + ", begain");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("name = " + Thread.currentThread().getName() + ", end");

}

// 对象锁

public synchronized void objectLock() {

System.out.println("name = " + Thread.currentThread().getName() + ", begain");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("name = " + Thread.currentThread().getName() + ", end");

}创建三个线程类:分别调用一个资源中的三个方法class ThreadA extends Thread {

private Test02 test02;

public ThreadA(Test02 tk) {

test02 = tk;

}

// 调用类锁

public void run() {

test02.classLockA();

}

}

class ThreadB extends Thread {

private Test02 test02;

public ThreadB(Test02 tk) {

test02 = tk;

}

// 调用类锁

public void run() {

test02.classLockB();

}

}

class ThreadC extends Thread {

private Test02 test02;

public ThreadC(Test02 tk) {

test02 = tk;

}

// 调用对象锁

public void run() {

test02.objectLock();

}

}main方法:起了三个线程,共同访问一个Test02对象public static void main(String[] args){

Test02 test02 = new Test02();

ThreadA ta = new ThreadA(test02);

ThreadB tb = new ThreadB(test02);

ThreadC tc = new ThreadC(test02);

ta.setName("A");

tb.setName("B");

tc.setName("C");

ta.start();

tb.start();

tc.start();

}执行的结果:name = A, begain

name = C, begain

name = A, end

name = B, begain

name = C, end

name = B, end可以看出由于 classLockA和classLockB都是类锁,即同一个锁,所以 A和B是按顺序执行,即同步的。而C是对象锁,和A/B不是同一种锁,所以C和A、B是 异步执行的。

分析:对象锁要想保持同步执行,那么锁住的必须是同一个对象,举个例子:

Test02类不变,重起两个线程类:均对对象锁进行了调用class ThreadA extends Thread {

private Test02 test02;

public ThreadA(Test02 tk) {

test02 = tk;

}

// 调用类锁

public void run() {

test02.objectLock();

}

}

class ThreadB extends Thread {

private Test02 test02;

public ThreadB(Test02 tk) {

test02 = tk;

}

// 调用类锁

public void run() {

test02.objectLock();

}

}main方法:创建两个不同的资源对象,启动两个线程,分别对加锁的方法进行调用public static void main(String[] args){

Test02 test02 = new Test02();

Test02 test03 = new Test02();

ThreadA ta = new ThreadA(test02);

ThreadB tb = new ThreadB(test03);

ta.setName("A");

tb.setName("B");

ta.start();

tb.start();

}结果可见,是异步执行的,没有达到同步的作用。name = A, begain

name = B, begain

name = A, end

name = B, end改进:只需对类锁进行调用,代码如下:class ThreadA extends Thread {

private Test02 test02;

public ThreadA(Test02 tk) {

test02 = tk;

}

// 调用类锁

public void run() {

test02.classLockA();

}

}

class ThreadB extends Thread {

private Test02 test02;

public ThreadB(Test02 tk) {

test02 = tk;

}

// 调用类锁

public void run() {

test02.classLockA();

}

}main方法:同样是创建了多个对象public static void main(String[] args){

Test02 test02 = new Test02();

Test02 test03 = new Test02();

ThreadA ta = new ThreadA(test02);

ThreadB tb = new ThreadB(test03);

ta.setName("A");

tb.setName("B");

ta.start();

tb.start();

}结果达到了同步的效果!name = A, begain

name = A, end

name = B, begain

name = B, end

总结:如果多线程同时访问同一类的 类锁(synchronized 修饰的静态方法)以及对象锁(synchronized 修饰的非静态方法)这两个方法执行是异步的,原因:类锁和对象锁是2中不同的锁。

类锁对该类的所有对象都能起作用,而对象锁不能。

synchronized锁的是对象。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号