网上看到一个题目,题目是这样:Java多线程,启动四个线程,两个执行加一,另外两个执行减一。
针对该问题写了一个程序,测试通过,如下:
class Sync {
static int count = 0;
public void add() {
synchronized (Sync.class) {
System.out.println("test开始..");
count++;
System.out.println("count = "+count);
System.out.println("test结束..");
}
}
public void sub() {
synchronized (Sync.class) {
System.out.println("test开始..");
count--;
System.out.println("count = "+count);
System.out.println("test结束..");
}
}
}
class MyThread extends Thread {
int operation = 0;
public MyThread(int operation) {
this.operation = operation;
}
public void run() {
Sync sync = new Sync();
if(operation==0){
sync.sub();
}else if(operation==1){
sync.add();
}
}
}
public class Main {
public static void main(String[] args) {
//t1,t2做加法
Thread t1 = new MyThread(1);
Thread t2 = new MyThread(1);
//t3,t4做减法
Thread t3 = new MyThread(0);
Thread t4 = new MyThread(0);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
输出结果:
test开始..
count = 1
test结束..
test开始..
count = 0
test结束..
test开始..
count = 1
test结束..
test开始..
count = 0
test结束..
分析:线程t1,t2执行加法操作,线程t3,t4执行减法操作。在该程序中有两个需要注意的点:
1.变量count必须定义为静态类型static,因为如果不是定义成static,则虽然4个线程锁住的是同一个对象,但是他们操作的count确实从属于不同的sync实例,因为每个线程的sync是线程内部创建的,而不是从外界统一注入,由于每个线程操作的count分属不同sync实例,导致结果具有随机性。count定义为static后,多个线程操作的count为Sync类的静态变量count,共享,结果为0.
2.这种实现的方式是一种比较低效的方式,分析代码,add()方法和sub()方法的锁对象也是相同的,即有一个线程在执行add()方法时,其他线程除了不能执行同步方法add()以外,sub()方法也不能执行,这是因为使用的全局锁,一个同步方法执行时,其他所有的同步方法都不能执行。