统计函数调用次数:
import java.lang.Thread;
public class CalculateCallTime implements Runnable {
private static int times = 0;
private static Object mem = new Object();
/**
* 方法1:
*/
public static synchronized void foo() {
times++;
System.out.println(times);
}
/**
* 方法2:
*/
public void foo() {
synchronized(mem) {
times++;
System.out.println(times);
}
}
/**
* 方法3:
* 输出结果为 begin begin begin 4 4 4
* 说明 static 修饰的函数可被多个对象同时访问
*/
public synchronized void foo() {
times++;
System.out.println("begin");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(times);
}
public static void main(String args[]) {
Thread thread1 = new Thread(new CalculateCallTime());
Thread thread2 = new Thread(new CalculateCallTime());
Thread thread3 = new Thread(new CalculateCallTime());
thread1.start();
thread2.start();
thread3.start();
}
@Override
public void run() {
this.foo();
}
}
如上,多线程环境下,方法1、方法2的执行不会有问题;
但是方法3会有问题,即输出的结果具有不确定性;
public static void main(String args[]) {
CalculateCallTime a = new CalculateCallTime();
Thread thread1 = new Thread(a);
Thread thread2 = new Thread(a);
Thread thread3 = new Thread(a);
thread1.start();
thread2.start();
thread3.start();
}
如果main函数中的调用这样修改,则不会出现线程同步问题,原因:
synchronized为对象同步锁,多线程下,调用foo()函数时,锁住对象a,使得thread2和thread3无法获取当前对象a,因此无法访问函数foo(),即不会出现多线程的同步问题;