高并发编程基础

1.同步方法锁定的是锁对应的其它同步方法,不影响调用非同步方法或其它锁对应的同步方法。

public class Test1 {
    Object o = new Object();

    public synchronized void m1() {
        System.out.println("public synchronized void m1() start");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("public synchronized void m1() end");
    }

    public void m2() {
        System.out.println("public void m2() start");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("public void m2() end");
    }

    public void m3() {
        synchronized (o) {
            System.out.println("public void m3() start");
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("public void m3() end");
        }
    }

    public static class MyThread01 implements Runnable {
        int i;
        Test1 t;

        public MyThread01(int i, Test1 t) {
            this.i = i;
            this.t = t;
        }

        public void run() {
            if (i == 0) {
                t.m1();
            } else if (i > 0) {
                t.m2();
            } else {
                t.m3();
            }
        }
    }

    public static void main(String[] args) {
        Test1 t = new Test1();
        new Thread(new Test1.MyThread01(0, t)).start();
        new Thread(new Test1.MyThread01(1, t)).start();
        new Thread(new Test1.MyThread01(-1, t)).start();
    }

}

2.同步方法只能保证当前方法的原子性,不能保证多个业务方法之间的互相访问的原子性。在开发中,如果要求多个方法保持对结果访问的原子性,需要给这些方法都加同一个锁。

public class Test2 {
    private double d = 0.0;

    public synchronized void m1(double d) {
        try {
            // 模拟复杂的业务代码,可能引发脏读
            TimeUnit.SECONDS.sleep(1);
            this.d = d;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public double m2() {
        return this.d;
    }

    public static void main(String[] args) {
        Test2 t = new Test2();
        new Thread(new Runnable() {
            public void run() {
                t.m1(100);
            }
        }).start();
        System.out.println(t.m2());// 打印0.0
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(t.m2());// 打印100.0
    }

}

3.一个线程执行多个同步代码块,这些同步代码块使用的是同一把锁,锁可重入。

public class Test3 {

    synchronized void m1() {// 锁是this
        System.out.println("m1 start");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        m2();
        System.out.println("m1 end");
    }

    synchronized void m2() {// 锁是this
        System.out.println("m2 start");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("m2 end");
    }

    public static void main(String[] args) {
        new Test3().m1();
    }

}

子类中覆盖了父类的同步方法,在子类的同步方法中可以调用父类的同步方法,锁可重入。

public class Test4 {

    synchronized void m() {
        System.out.println("Super Class m start");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Super Class m end");
    }

    public static void main(String[] args) {
        new Sub_Test4().m();
    }

}

class Sub_Test4 extends Test4 {
    synchronized void m() {
        System.out.println("Sub Class m start");
        super.m();
        System.out.println("Sub Class m end");
    }
}

你可能感兴趣的:(高并发编程基础)