首先什么是类锁?
就像可以对类的每一个实例(对象)获取一个对象锁一样,对于每一个类都可以获取一个锁,我们称之为类锁。
然后为什么要有静态锁?
简而言之,一个非静态方法获取静态锁通常是为了在防止静态数据上发生竞态条件。因为静态方法是属于类的,即对于静态方法而言是没有对象引用的概念的,那么此时就无法使用对象来对静态方法进行锁定了。我们可以做这样的考虑,就是既然静态方法是属于类的,那么我们是否可以使用类对象来做锁定依据呢?答案是肯定的,我们可以使用表示当前类的类对象或者从属于当前类静态域的静态对象来做锁的判断依据。
使用方法
一个简单的例子,对比使用了静态锁和没使用了静态锁的两种情况
package com.wly.javathread.chap3;
/**
* 测试静态锁(类锁)的使用
* 静态锁(类锁)主要用来防止在静态数据上发生竞态条件,理论依据是要操作静态数据必须先获取到静态锁(类锁)的原理
* @author wly
*
*/
public class TestStaticLock {
static Score2 score2;
static Score1 score1;
/**
* @param args
*/
public static void main(String[] args) {
//测试没有加静态锁的情况
System.out.println("--测试没有加静态锁的情况--");
Thread[] threads = new Thread[1000];
for(int j=0;j<10;j++) { //循环测试多次
score1 = new Score1();
for(int i=0;i<threads.length;i++) {
threads[i] = new Thread() {
@Override
public void run() {
super.run();
score1.add(10);
try {
this.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
score1.deduct(10);
}
};
threads[i].start();
}
//等待所有线程都结束
for(int i=0;i<threads.length;i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
score1.printScore();
}
//测试加了静态锁的情况
System.out.println("--测试加了静态锁的情况--");
for(int j=0;j<10;j++) { //循环测试多次
score2 = new Score2();
for(int i=0;i<threads.length;i++) {
threads[i] = new Thread() {
@Override
public void run() {
super.run();
score2.add(10);
try {
this.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
score2.deduct(10);
}
};
threads[i].start();
}
//等待所有线程都结束
for(int i=0;i<threads.length;i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
score2.printScore();
}
}
}
/**
* 没有加静态锁的实现
* @author wly
*
*/
class Score1 {
static int score;
public void add(int num) {
score += num;
}
public void deduct(int num) {
score -= num;
}
public void printScore() {
System.out.println("score:" + score);
}
}
/**
* 加了静态锁的实现
* @author wly
*
*/
class Score2 {
static int score;
public void add(int num) {
synchronized (Score2.class) {
score += num;
}
}
public void deduct(int num) {
synchronized (Score2.class) {
score -= num;
}
}
public void printScore() {
System.out.println("score:" + score);
}
}
运行结果:
--测试没有加静态锁的情况--
score:10
score:10
score:10
score:10
score:20
score:10
score:10
score:10
score:10
score:10
--测试加了静态锁的情况--
score:0
score:0
score:0
score:0
score:0
score:0
score:0
score:0
score:0
score:0
类锁和对象锁
类锁和对象锁是两种不同的锁,如果一个非静态同步方法调用了一个静态同步方法,它就拥有了两个不同的锁。因为一个静态同步方法在没有对象引用的情况下不调用能非静态同步方法,所以这两种同步方法发生死锁的概率很小。
其他锁定方式
a.使用其他静态对象做锁定依据
public class Test {
private static int count = 0;
private static final Object countLock = new Object();
public void incrementCount() {
synchronized (countLock) {
count++;
}
}
}
b.在静态方法上使用synchronized修饰符
public class Test {
private static int count = 0;
public static synchronized void incrementCount() {
count++;
}
}
O啦~~~
装载请保留出处:http://blog.csdn.net/u011638883/article/details/18040949
谢谢!!