Thread thread2 = new Thread() {
@Override
public void run() {
test2.function();
}
};
thread1.start();
thread2.start();
}
}
class TestCase {
public synchronized static void function() {// add static keyword.
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread()。getName() + " executed result: " + i);
}
}
}
执行程序,运行结果总是如下:
Thread-0 executed result: 0
Thread-0 executed result: 1
Thread-0 executed result: 2
Thread-0 executed result: 3
Thread-0 executed result: 4
Thread-1 executed result: 0
Thread-1 executed result: 1
Thread-1 executed result: 2
Thread-1 executed result: 3
Thread-1 executed result: 4
从结果可以看出,两个线程顺序执行。而上面的[测试程序2.2]两个线程是交叉输出的。为什么同步静态方法会起到两个对象也能同步的了呢?
因为被static修饰的方法是静态方法,也被称为类方法,表明这个方法是属于类的。与普通方法的区别是,在类被加载进内存时,就分配了方法的入口地址,而普通方法要实例化对象后才分配方法的入口地址。
所以对静态方法进行同步,相当于是锁住了类,当一个线程进入这个静态方法时,其他线程无论使用这个类的哪个对象都无法进入这个静态方法,直到上一个线程执行完毕释放锁。
同样的当一个线程进入这个静态方法时,其他线程也进不去这个类的其他被同步的静态方法,因为只要是静态方法都是属于类的嘛。但是可以进入其他未同步的方法(包括静态方法)。这些可以自己来测试,就不上例子了。
但是这种方式,与完全的同步类又有些区别,我们可以继续看下面的程序。
[测试程序3.2]
/**
* Test case 3.2. synchronized static method.
*/
public class Test {
public static void main(String[] args) {
// There are two objects.
final TestCase test = new TestCase();
Thread thread1 = new Thread() {
@Override
public void run() {
test.function1();
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
test.function2();
}
};
thread1.start();
thread2.start();
}
}
class TestCase {
public synchronized static void function1() {// add static keyword.
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread()。getName() + " executed result: " + i);
}
}
public synchronized void function2() {// no static keyword.
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread()。getName() + " executed result: " + i);
}
}
}
执行程序,某次的运行结果如下:
Thread-0 executed result: 0
Thread-1 executed result: 0
Thread-1 executed result: 1
Thread-1 executed result: 2
Thread-0 executed result: 1
Thread-0 executed result: 2
Thread-1 executed result: 3
Thread-1 executed result: 4
Thread-0 executed result: 3
Thread-0 executed result: 4
从以上结果可以看出,虽然静态方法和普通方法都被同步,虽然是对同一个对象,但是两个线程仍然交叉执行。说明当一个线程进入了类的静态同步方法,其他线程可以进入这个类的非静态的同步方法。
同步静态方法小结
在多线程中,同步静态方法时:
同步静态方法时,相当于对类所有的类方法上锁,但并不是完全的类同步;
一个线程进入这个类的静态同步方法时,其他线程无法进入这个类的其他静态同步方法;
但是其他线程可以进入这个类的非静态方法(无论是否同步)
至于未同步的方法,无论是否是静态方法,都是想进就进啦。