Given two strings ABCDEF and 123456, use two threads to output in the order 1A2B3C4D5E6F

This question examines the understanding of multi-threading and certain classes under JUC. In general, the idea is that after one thread t1 outputs the current character, it needs to block or wait for another thread t2 to output, and then t2 blocks or waits. , there are several ideas as follows. Without further ado, let’s go directly to the code.

1. Use the traditional sychronized locking method:

public class OrderPrintSynchronized {
    public static String s1 = "123456";
    public static String s2 = "ABCDEF";

    public static Object lock = new Object();

    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            int length = s1.length();
            synchronized (lock) {
                for (int i = 0; i < length; i++) {
                    System.err.println(s1.charAt(i));
                    try {
                        lock.notify();
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lock.notify();
            }
        });
        Thread t2 = new Thread(() -> {
            int length = s2.length();
            synchronized (lock) {
                for (int i = 0; i < length; i++) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.err.println(s2.charAt(i));
                    lock.notify();
                }
            }
        });
        t2.start();
        TimeUnit.SECONDS.sleep(1);
        t1.start();
        TimeUnit.SECONDS.sleep(1);
    }
}

2. Use LockSupport:

public class OrderPrintLockSupport {
    public static String s1 = "123456";
    public static String s2 = "ABCDEF";
    private static Thread t1;
    private static Thread t2;

    public static void main(String[] args) throws Exception {
        t1 = new Thread(() -> {
            int length = s1.length();
            for (int i = 0; i < length; i++) {
                System.err.println(s1.charAt(i));
                LockSupport.unpark(t2);
                LockSupport.park();
            }
        });
        t2 = new Thread(() -> {
            int length = s2.length();
            for (int i = 0; i < length; i++) {
                LockSupport.park();
                System.err.println(s2.charAt(i));
                LockSupport.unpark(t1);
            }
        });
        t2.start();
        TimeUnit.SECONDS.sleep(1);
        t1.start();
        TimeUnit.SECONDS.sleep(1);
    }
}

3. Use SynchronousQueue and TransferQueue. The two principles are similar. They both use the queue to have only one element and this element must be processed by another thread. Otherwise, the current thread will always be blocked. It is opportunistic here to let the other one The thread outputs the data originally output by the current thread:

import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TransferQueue;

public class OrderPrintTransferQueue {
    public static String s1 = "123456";
    public static String s2 = "ABCDEF";

    private static TransferQueue<String> stringSynchronousQueue = new LinkedTransferQueue<>();

    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            int length = s1.length();
            for (int i = 0; i < length; i++) {
                try {
                    stringSynchronousQueue.put(s1.charAt(i) + "");
                    System.err.println(stringSynchronousQueue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread t2 = new Thread(() -> {
            int length = s2.length();
            for (int i = 0; i < length; i++) {
                try {
                    System.err.println(stringSynchronousQueue.take());
                    stringSynchronousQueue.put(s2.charAt(i) + "");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t2.start();
        TimeUnit.SECONDS.sleep(1);
        t1.start();
        TimeUnit.SECONDS.sleep(1);
    }
}
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

public class OrderPrintSynchronousQueue {
    public static String s1 = "123456";
    public static String s2 = "ABCDEF";

    private static SynchronousQueue<String> stringSynchronousQueue = new SynchronousQueue<>();

    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            int length = s1.length();
            for (int i = 0; i < length; i++) {
                try {
                    stringSynchronousQueue.put(s1.charAt(i) + "");
                    System.err.println(stringSynchronousQueue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread t2 = new Thread(() -> {
            int length = s2.length();
            for (int i = 0; i < length; i++) {
                try {
                    System.err.println(stringSynchronousQueue.take());
                    stringSynchronousQueue.put(s2.charAt(i) + "");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t2.start();
        TimeUnit.SECONDS.sleep(1);
        t1.start();
        TimeUnit.SECONDS.sleep(1);
    }
}

4. Atomic plus spin:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class OrderPrintAtomic {
    public static String s1 = "123456";
    public static String s2 = "ABCDEF";

    private static AtomicBoolean atomicBoolean = new AtomicBoolean(false);

    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            int length = s1.length();
            for (int i = 0; i < length; i++) {
                while (!atomicBoolean.get()) {
                    break;
                }
                System.err.println(s1.charAt(i));
                atomicBoolean.set(true);
            }
        });
        Thread t2 = new Thread(() -> {
            int length = s2.length();
            for (int i = 0; i < length; i++) {
                while (atomicBoolean.get()) {
                    break;
                }
                System.err.println(s2.charAt(i));
                atomicBoolean.set(false);
            }
        });
        t2.start();
        TimeUnit.SECONDS.sleep(1);
        t1.start();
        TimeUnit.SECONDS.sleep(1);
    }
}

Guess you like

Origin blog.csdn.net/qq_17805707/article/details/133135586