JUC学习-2

public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "A").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "B").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "C").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "D").start();


    }
}


class Data {
    int number = 0;

    public synchronized void increment() throws InterruptedException {
        if (number != 0) {
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName() + "=====" + number);
        this.notifyAll();
    }

    public synchronized void decrement() throws InterruptedException {
        if (number == 0) {
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName() + "=====" + number);
        this.notifyAll();
    }
}

JUC学习-2

防止虚假唤醒

因为超过2个线程唤醒的时候会全部唤醒,所以if改为while判断 因为if判断只会判断一次


class Data3 {
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();
    private int number = 1;

    public void printA() {
        try {
            lock.lock();
            while (number != 1) {
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName() + "A");
            number = 2;
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printB() {
        try {
            lock.lock();
            while (number != 2) {
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName() + "B");
            number = 3;
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printC() {
        try {
            lock.lock();
            while (number != 3) {
                condition3.await();
            }
            System.out.println(Thread.currentThread().getName() + "C");
            number = 1;
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

创建多个Condition可以精准通知

锁的各种现象

代码:

public class Test1 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> {
            try {
                phone.sendSms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();



        new Thread(() -> {
            phone.call();
        }, "B").start();

    }
}

class Phone {

    // synchronized 锁的对象是方法的调用者
    // 俩个方法用的是同一把锁 谁先拿到谁执行

    public synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }
}



public class Test2 {
    public static void main(String[] args) throws InterruptedException {

        // 2个对象是2个锁 不会相互影响
        Phone2 phone1 = new Phone2();
        Phone2 phone2 = new Phone2();
        new Thread(() -> {
            try {
                phone1.sendSms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(() -> {
            phone2.call();
        }, "B").start();

    }
}

class Phone2 {

    // synchronized 锁的对象是方法的调用者
    // 俩个方法用的是同一把锁 谁先拿到谁执行

    public synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }

    // 普通方法不受锁的影响
    public  void hello() {
        System.out.println("hello");
    }
}




public class Test3 {
    public static void main(String[] args) throws InterruptedException {
        // 2个对象只有一个Class对象 static 锁的是Class
        Phone3 phone1 = new Phone3();
        Phone3 phone2 = new Phone3();
        new Thread(() -> {
            try {
                phone1.sendSms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(() -> {
            phone2.call();
        }, "B").start();

    }
}


class Phone3 {

    // 把同步方法转为静态方法
    // 类一加载就有了  锁的是Class 模板
    // Phone3只有一个Class对象

    public static synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("发短信");
    }

    public static synchronized void call() {
        System.out.println("打电话");
    }


}


public class Test4 {
    public static void main(String[] args) throws InterruptedException {
        Phone4 phone = new Phone4();
        // 先执行打电话 因为锁的不是一个东西
        new Thread(() -> {
            try {
                phone.sendSms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(() -> {
            phone.call();
        }, "B").start();

    }
}


class Phone4 {

    // 静态的同步方法 锁的Class
    public static synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("发短信");
    }

    // 普通同步方法 锁的对象
    public synchronized void call() {
        System.out.println("打电话");
    }


}

总结: 锁是锁的对象 static锁的是Class模板

上一篇:多个线程操作一个变量(synchronized)


下一篇:仿网易云音乐日推界面(监听AppBarLayout滑动+动态高斯模糊