首先来简单介绍一下static和synchronized这两个属性;

static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。

被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。

synchronized:在java中是同步的意思。是内置语言级的同步原语,这也大大简化了Java中多线程同步的使用。

第一种实例:

public class TestSync implements Runnable {
    Sync s = new Sync();
    public static void main(String[] args) {
        Thread t1 = new Thread(new TestSync());
        Thread t2 = new Thread(new TestSync());
        t1.start();
        t2.start();
    }
    // 重写run方法
    public void run() {
        s.add();
    }
}
class Sync {
    static int num;
    public synchronized void add() {
        try {
        num++;
                                                                                                                                      
        } catch (Exception e) {
            System.out.println("抱歉!当前线程执行到这里中断了。");
        }
        System.out.println("当前是第" + num + "个线程执行到这里");
    }
}

在这个实例里面的第15行我使用了 static 。这样输出结果为:

当前是第1个线程执行到这里
当前是第2个线程执行到这里

虽然这样输出的结果是正确的。但是同步锁并没有起到作用。因为Sync 是两个不同 实例。它没有被共用。虽然num被共用到。一旦在Sync 里面加上线程等待sleep或wait,这样输出的结果就会是两个相同或者多个相同的 结果。这样是非常不安全的。

如:

public class TestSync implements Runnable {
    Sync s = new Sync();
    public static void main(String[] args) {
//      Thread t2 = new Thread(new TestSync());
        for (int i = 0; i <10; i++) {
            Thread t1 = new Thread(new TestSync());
            t1.start();
        }
//      t2.start();
    }
    // 重写run方法
    public void run() {
        s.add();
    }
}
class Sync {
    static int num;
    public synchronized void add() {
        try {
        num++;
        Thread.sleep(10);
        } catch (Exception e) {
            System.out.println("抱歉!当前线程执行到这里中断了。");
        }
        System.out.println("当前是第" + num + "个线程执行到这里");
    }
}

当前是第10个线程执行到这里
当前是第10个线程执行到这里
当前是第10个线程执行到这里
当前是第10个线程执行到这里
当前是第10个线程执行到这里
当前是第10个线程执行到这里
当前是第10个线程执行到这里
当前是第10个线程执行到这里
当前是第10个线程执行到这里
当前是第10个线程执行到这里

正确用法是在Sync 实例前加上static。实现共用:

public class TestSync implements Runnable {
    static Sync s = new Sync();
    public static void main(String[] args) {
//      Thread t2 = new Thread(new TestSync());
        for (int i = 0; i <10; i++) {
            Thread t1 = new Thread(new TestSync());
            t1.start();
        }
//      t2.start();
    }
    // 重写run方法
    public void run() {
        s.add();
    }
}
class Sync {
    int num;
    public synchronized void add() {
        try {
        num++;
        Thread.sleep(10);
        } catch (Exception e) {
            System.out.println("抱歉!当前线程执行到这里中断了。");
        }
        System.out.println("当前是第" + num + "个线程执行到这里");
    }
}


当前是第1个线程执行到这里
当前是第2个线程执行到这里
当前是第3个线程执行到这里
当前是第4个线程执行到这里
当前是第5个线程执行到这里
当前是第6个线程执行到这里
当前是第7个线程执行到这里
当前是第8个线程执行到这里
当前是第9个线程执行到这里
当前是第10个线程执行到这里