多线程轮流交替执行三种实现方法

第一种方法:采用公平锁实现

思路及其简单:

  1. A线程拿到锁,执行代码
  2. B线程拿到锁,执行代码
  3. A线程拿到锁,执行代码
  4. ......
public class FairLockDemo {

    public static void main(String[] args) {

        Runnable target = new Runnable(){

            int i = 10;

            // 利用公平锁
            private ReentrantLock lock = new ReentrantLock(true);

            @Override
            public void run() {

                while (i >= 0) {
                    try{
                        lock.lock();
                        if(i % 2 == 0){
                            System.out.println("A");
                        }else {
                            System.out.println("B");
                        }
                        i--;
                    }finally{
                        lock.unlock();
                    }
                }
            }
        };

        Thread t1 = new Thread(target, "thread-1");
        Thread t2 = new Thread(target, "thread-2");
        t1.start();
        t2.start();
    }
}


第二种方法:采用synchronized对象锁 + wait + notify实现

思路比较复杂,值得细细揣摩:

  • 关键点:每个线程都有获得锁的权利
  • 1、满足if条件的,wait等待释放锁
  • 2、不满足if条件的,执行业务代码
public class TestThead {

    // 对象锁
    private static Object obj = new Object();
    private static volatile int num = 10;

    public static void main(String[] args) {

        new Thread(new Runnable() {           // 匿名内部类
            @Override
            public void run() {
                synchronized (obj) {
                    while(num > 0){
                        if(num % 2 == 0){
                            try {
                                obj.wait();   // 释放锁进入等待队列(等待池),线程2获取到对象锁
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        num--;
                        if(num >= 0){
                            System.out.println("B");
                        }
                        obj.notify();         // 唤醒等待队列中线程2进入锁池竞争对象锁
                    }
                }
            }
        }, "thread1").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (obj) {
                    while(num > 0){
                        if(num % 2 != 0){
                            try {
                                obj.wait();   // 释放锁进入等待队列(等待池),线程1获取到对象锁
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        num--;
                        if(num >= 0){
                            System.out.println("A");
                        }
                        obj.notify();       // 唤醒等待队列中线程1进入锁池竞争对象锁
                    }
                }
            }
        }, "thread2").start();
    }
}


3、采用Lock和Condition实现

思路:

  • 其实和上面的思路差不多
  • 只不过上面用了同一个对象锁,思考起来比较麻烦
  • 这里采用了两个锁,轮流开闭,思考起来很方便
public class LockCond {

    private static volatile int count = 10;
    private static Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        Condition c1 = lock.newCondition();
        Condition c2 = lock.newCondition();

        new Thread(()->{
            while(count > 0) {
                lock.lock();
                try {
                    if(count % 2 == 0) {
                        System.out.println("A");
                        c1.await();
                    }
                    //唤醒线程2
                    c2.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    count--;
                    lock.unlock();
                }
            }
        }) .start();

        new Thread(()->{
            while(count > 0) {
                lock.lock();
                try {
                    if(count % 2 == 1) {
                        System.out.println("B");
                        c2.await();
                    }
                    //唤醒线程1
                    c1.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    count--;
                    lock.unlock();
                }
            }
        }) .start();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章