Java线程同步使用案例

2019-06-09

  • 提供两种实现方式:【1】JVM通过对象头锁标记和monitor监视器实现的synchronized【2】JDK提供的可重入锁ReentrantLockCondition
  • 看到volatile修饰的FLAG字段,下面有FLAG++操作。熟悉volatile的同学会敏锐的想到,这个操作不是原子操作,线程不安全。但对于本题,我们用了lock做同步,当然就不用担心线程不安全的情况啦
  • lock.lock()如果放在while循环体内也可以实现,体现了可重入锁的特性,但要注意每获取一次锁就要释放一次锁
package cn.com.duiba.miria.missile.service;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author wrj
 * @date 2019/6/9
 */
public class ABC implements Runnable {

    private static volatile int FLAG = 0;
    private final static Object object = new Object();
    private final static Lock lock = new ReentrantLock();
    private final static Condition condition = lock.newCondition();
    private final int selfFlag;

    public ABC(int selfFlag) {
        this.selfFlag = selfFlag;
    }

    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see Thread#run()
     */
    @Override
    public void run() {
        lockCondition();
    }

    private void lockCondition() {
        lock.lock();
        try {
            while (true) {
                if (FLAG % 3 == selfFlag) {
                    System.out.print((char) ('A' + selfFlag));
                    FLAG++;
                    condition.signalAll();
                } else {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } finally {
            lock.unlock();
        }
    }

    private void waitNotify() {
        synchronized (object) {
            while (true) {
                if (FLAG % 3 == selfFlag) {
                    System.out.print((char) ('A' + selfFlag));
                    FLAG++;
                    object.notifyAll();
                } else {
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new ABC(0)).start();
        new Thread(new ABC(1)).start();
        new Thread(new ABC(2)).start();
    }
}