两个线程,一个输出字母一个输出数字,输出A1B2C3....Z26

思路1 :用一个变量记录属于哪个线程执行,然后另外一个线程阻塞掉即可。

public class main {
    static volatile int a = 1;
    public static void main(String[] args) {
        new  Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0 ; i < 26 ; i++){
                    while(a % 2 == 1){
                        try {
                            Thread.currentThread().interrupt();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(a/2);
                    a = a+1;
                }
            }
        }).start();
        new  Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0 ; i < 26 ; i++){
                    while(a % 2 == 0){
                        try {
                            Thread.currentThread().interrupt();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println((char)((a/2)+'A'));
                    a = a+1;
                }
            }
        }).start();
    }
}

思路2 :使用LockSupport中的unpark和park方法唤醒对方线程并阻塞当前线程。

import java.util.concurrent.locks.LockSupport;

public class Test_LockSupport {
    static Thread t1 = null,t2 = null;
    public static void main(String[] args) {
        char []aI = "123456789".toCharArray();
        char []aC = "ABCDEFJHI".toCharArray();
        t1 = new Thread(()->{
            for (char c : aI) {
                System.out.println(c);
                LockSupport.unpark(t2);//唤醒t2
                LockSupport.park();//阻塞t1
            }
        },"t1");
        t2 = new Thread(()->{
            for (char c : aC) {
                LockSupport.park();//阻塞t2,等着t1叫醒它
                System.out.println(c);
                LockSupport.unpark(t1);//唤醒t1

            }
        },"t2");
        t1.start();
        t2.start();
    }
}

思路3:CAS自旋锁的思路,一个线程while死循环等待。

public class test_cas {
    enum ReadToRun{T1,T2}
    static volatile  ReadToRun r = ReadToRun.T1;

    public static void main(String[] args) {
        char []aI = "123456789".toCharArray();
        char []aC = "ABCDEFJHI".toCharArray();
        new Thread(()->{
            for (char c : aI) {
                while(r != ReadToRun.T2){

                }
                System.out.println(c);
                r = ReadToRun.T1;
            }
        },"t1").start();
        new Thread(()->{
            for (char c : aC) {
                while(r != ReadToRun.T1) {

                }
                System.out.println(c);
                r = ReadToRun.T2;
            }
        },"t2").start();
    }

思路4:sync锁  wait notify(注意wait notify顺序不能换)

public class test_sync_wait_notify {
    public static void main(String[] args) {
        char []aI = "123456789".toCharArray();
        char []aC = "ABCDEFJHI".toCharArray();
        final  Object o = new Object();

        new Thread(()->{
            synchronized (o){
                for (char c : aI) {
                    System.out.println(c);
                    try {
                        o.notify();//叫醒另外一个线程
                        o.wait();//让出锁
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();//必须 否则无法停止程序
            }
        },"t1").start();

        new Thread(()->{
            synchronized (o){
                for (char c : aC) {
                    System.out.println(c);
                    try {
                        o.notify();
                        o.wait();//让出锁
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();//必须 否则无法停止程序
            }
        },"t2").start();
    }
}

 可以用CountDownLatch控制先后。

import java.util.concurrent.CountDownLatch;

public class test_sync_wait_notify {


    private static CountDownLatch countDownLatch = new CountDownLatch(1);//控制两个线程先后
    public static void main(String[] args) {
        char []aI = "123456789".toCharArray();
        char []aC = "ABCDEFJHI".toCharArray();
        final  Object o = new Object();

        new Thread(()->{
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (o){
                for (char c : aC) {
                    System.out.println(c);
                    try {
                        o.notify();//叫醒另外一个线程
                        o.wait();//让出锁
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();//必须 否则无法停止程序
            }
        },"t1").start();

        new Thread(()->{
            synchronized (o){
                for (char c : aI) {
                    System.out.println(c);
                    countDownLatch.countDown();
                    try {
                        o.notify();
                        o.wait();//让出锁
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();//必须 否则无法停止程序

            }
        },"t2").start();
    }
}

思路5:reentrantlock和condition实现。

public class test_Lock_Condition {
    public static void main(String[] args) {
        char []aI = "123456789".toCharArray();
        char []aC = "ABCDEFJHI".toCharArray();
        Lock lock = new ReentrantLock();
        //condition是一个队列,有一个condition就有一个队列,好处是指定哪个队列唤醒
        Condition conditionT1 = lock.newCondition();
        Condition conditionT2 = lock.newCondition();
        new Thread(()->{
            try{
                lock.lock();//锁住,相当于sync
                for (char c : aI) {
                    System.out.println(c);
                    conditionT2.signal();//叫醒conditionT2队列的线程
                    conditionT1.await();
                }
                conditionT2.signal();
            }catch (Exception e){
                e.printStackTrace();
            }
            finally {
                lock.unlock();
            }
        },"t1").start();

        new Thread(()->{
            try{
                lock.lock();
                for (char c : aC) {
                    System.out.println(c);
                    conditionT1.signal();
                    conditionT2.await();
                }
                conditionT1.signal();
            }catch (Exception e){
                e.printStackTrace();
            }
            finally {
                lock.unlock();
            }
        },"t2").start();
    }
}

     

原文地址:https://www.cnblogs.com/Esquecer/p/12517220.html