2个线程交替打印数据(多种方案)

public class PrinterAB {

    private final Object monitor = new Object();
    private int limit;

    private PrinterAB(int limit) {
        this.limit = limit;
    }

    private void sycFoo() {
        for (int i = 0; i < limit; i++) {
            synchronized (monitor) {
                while (!flag) {
                    try {
                        monitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + ": foo");
                flag = false;
                monitor.notifyAll();
            }
        }
    }

    private void sycBar() {
        for (int i = 0; i < limit; i++) {
            synchronized (monitor) {
                while (flag) {
                    try {
                        monitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + ": bar");
                flag = true;
                monitor.notifyAll();
            }
        }
    }


    private Semaphore foo = new Semaphore(1);
    private Semaphore bar = new Semaphore(0);

    private void semFoo() {
        for (int i = 0; i < limit; i++) {
            try {
                foo.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ": foo");
            //每个release()方法都会释放持有许可证的线程,并且归还Semaphore一个可用的许可证。
            bar.release();
        }
    }

    private void semBar() {
        for (int i = 0; i < limit; i++) {
            try {
                bar.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ": bar");
            foo.release();
        }
    }

    private BlockingQueue<Integer> blockBar = new LinkedBlockingQueue<>(1);

    private void queueFoo() {
        for (int i = 0; i < limit; i++) {
            try {
                blockBar.put(i);
                System.out.println(Thread.currentThread().getName() + ": foo," + i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void queueBar() {
        for (int i = 0; i < limit; i++) {
            try {
                blockBar.take();
                System.out.println(Thread.currentThread().getName() + ": bar," + i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    //CyclicBarrier: 可循环(cyclic)使用的屏障。组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,所有被屏障拦截的线程才会继续干活
    private CyclicBarrier cb = new CyclicBarrier(2);
    private volatile boolean fin = true;

    private void cycFoo() {
        for (int i = 0; i < limit; i++) {

            while (!fin) ;
            fin = false;
            System.out.println(Thread.currentThread().getName() + ": foo," + i);
            try {
                cb.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }

        }
    }

    private void cycBar() {
        for (int i = 0; i < limit; i++) {

            try {
                cb.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + ": bar," + i);
            fin = true;
        }
    }


    private volatile boolean permitFoo = true;

    private void perFoo() {
        for (int i = 0; i < limit; ) {
            if (permitFoo) {
                System.out.println(Thread.currentThread().getName() + ": foo," + i);
                i++;
                permitFoo = false;
            } else {
                //使用Thread.yield,来防止超时
                Thread.yield();
            }
        }
    }

    private void perBar() {
        for (int i = 0; i < limit; ) {
            if (!permitFoo) {
                System.out.println(Thread.currentThread().getName() + ": bar," + i);
                i++;
                permitFoo = true;
            } else {
                Thread.yield();
            }
        }
    }

    private Lock reentrantLock = new ReentrantLock(true);
    private final Condition cond = reentrantLock.newCondition();
    private volatile boolean flag = true;

    private void reFoo() {
        for (int i = 0; i < limit; i++) {
            reentrantLock.lock();
            try {
                while (!flag) {
                    try {
                        cond.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + ": foo," + i);
                flag = false;
                cond.signal();
            } finally {
                reentrantLock.unlock();
            }
        }
    }

    private void reBar() {
        for (int i = 0; i < limit; i++) {
            reentrantLock.lock();
            try {
                while (flag) {
                    try {
                        cond.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + ": bar," + i);
                flag = true;
                cond.signal();
            } finally {
                reentrantLock.unlock();
            }
        }
    }

    //Exchanger类可用于两个线程之间交换信息。可简单地将Exchanger对象理解为一个包含两个格子的容器,通过exchanger方法可以向两个格子中填充信息。
    // 当两个格子中的均被填充时,该对象会自动将两个格子的信息交换,然后返回给线程,从而实现两个线程的信息交换。
    //超过两个线程,得到的结果是随机的.未配对的线程,则会被阻塞,永久等待,直到与之配对的线程到达位置.
    private Exchanger<Integer> ex1 = new Exchanger<>();
    private Exchanger<Integer> ex2 = new Exchanger<>();

    private void exFoo() {

        for (int i = 0; i < limit; i++) {
            System.out.println(Thread.currentThread().getName() + ": foo," + i);
            try {
                ex1.exchange(1);
                ex2.exchange(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void exBar() {

        for (int i = 0; i < limit; i++) {
            try {
                ex1.exchange(2);
                System.out.println(Thread.currentThread().getName() + ": bar," + i);
                ex2.exchange(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static Thread thread15=null;
    private static Thread thread16 = null;
    
    public static void main(String[] args) throws InterruptedException {
        PrinterAB printer = new PrinterAB(10000);

        Thread thread1 = new Thread(printer::semFoo, "1");
        Thread thread2 = new Thread(printer::semBar, "2");
        Thread thread3 = new Thread(printer::queueFoo, "3");
        Thread thread4 = new Thread(printer::queueBar, "4");
        Thread thread5 = new Thread(printer::cycFoo, "5");
        Thread thread6 = new Thread(printer::cycBar, "6");
        Thread thread7 = new Thread(printer::perFoo, "7");
        Thread thread8 = new Thread(printer::perBar, "8");
        Thread thread9 = new Thread(printer::reFoo, "9");
        Thread thread10 = new Thread(printer::reBar, "10");
        Thread thread11 = new Thread(printer::exFoo, "11");
        Thread thread12 = new Thread(printer::exBar, "12");
        Thread thread13 = new Thread(printer::sycFoo, "13");
        Thread thread14 = new Thread(printer::sycBar, "14");
    
    //LockSupport
        thread15 = new Thread(() -> {
          for (int i = 0; i < 10000; i++) {
                System.out.println(Thread.currentThread().getName() + ": foo," + i);
                LockSupport.unpark(thread16);
                LockSupport.park();
            }
        }, "15");    
    
        thread16 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {
                LockSupport.park();
                System.out.println(Thread.currentThread().getName() + ": bar," + i);
                LockSupport.unpark(thread15);
            }
        }, "16");

        long l1 = System.currentTimeMillis();
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        long l2 = System.currentTimeMillis();

        thread3.start();
        thread4.start();
        thread3.join();
        thread4.join();
        long l3 = System.currentTimeMillis();

        thread5.start();
        thread6.start();
        thread5.join();
        thread6.join();
        long l4 = System.currentTimeMillis();

        thread7.start();
        thread8.start();
        thread7.join();
        thread8.join();
        long l5 = System.currentTimeMillis();

        thread9.start();
        thread10.start();
        thread9.join();
        thread10.join();
        long l6 = System.currentTimeMillis();

        thread11.start();
        thread12.start();
        thread11.join();
        thread12.join();
        long l7 = System.currentTimeMillis();

        thread13.start();
        thread14.start();
        thread13.join();
        thread14.join();
        long l8 = System.currentTimeMillis();

        thread15.start();
        thread16.start();
        thread15.join();
        thread16.join();
        long l9 = System.currentTimeMillis();

        System.out.println(".......................................................");
        System.out.println("Semaphore信号量:" + (l2 - l1));
        System.out.println("BlockingQueue阻塞队列:" + (l3 - l2));
        System.out.println("CyclicBarrier循环栅栏:" + (l4 - l3));
        System.out.println("yield:" + (l5 - l4));
        System.out.println("cas/reentrantLock:" + (l6 - l5));
        System.out.println("Exchanger:" + (l7 - l6));
        System.out.println("synchronized:" + (l8 - l7));
        System.out.println("lockSupport:" + (l9 - l8));
    }
}

一万条数据运行结果

Semaphore信号量:227
BlockingQueue阻塞队列:301
CyclicBarrier循环栅栏:539
yield:991
reentrantLock:284
Exchanger:922
synchronized:165
lockSupport:181
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用多线程编程来实现三个线交替打印abc。下面是一个示例代码: ```python import threading class PrintABC: def __init__(self): self.current_letter = 'A' self.lock = threading.Lock() def print_a(self): for _ in range(10): with self.lock: while self.current_letter != 'A': self.lock.wait() print('A', end='') self.current_letter = 'B' self.lock.notify_all() def print_b(self): for _ in range(10): with self.lock: while self.current_letter != 'B': self.lock.wait() print('B', end='') self.current_letter = 'C' self.lock.notify_all() def print_c(self): for _ in range(10): with self.lock: while self.current_letter != 'C': self.lock.wait() print('C', end='') self.current_letter = 'A' self.lock.notify_all() def main(): printer = PrintABC() thread_a = threading.Thread(target=printer.print_a) thread_b = threading.Thread(target=printer.print_b) thread_c = threading.Thread(target=printer.print_c) thread_a.start() thread_b.start() thread_c.start() thread_a.join() thread_b.join() thread_c.join() if __name__ == '__main__': main() ``` 这个例子中,我们创建了一个 `PrintABC` 类,其中包含了三个方法 `print_a`、`print_b` 和 `print_c` 分别用于打印字母 'A'、'B' 和 'C'。在每个方法中,使用 `with self.lock` 来获取锁对象并进入临界区域。通过 `self.current_letter` 来确定当前应该打印的字母,并使用 `while self.current_letter != 'A'` 等待其他线程改变 `self.current_letter` 的值。当当前字母符合要求时,打印字母并切换到下一个字母,然后使用 `self.lock.notify_all()` 唤醒其他等待的线程。 在 `main` 方法中,我们创建了三个线程并分别启动它们,然后使用 `join` 方法等待所有线程执行完毕。运行这段代码时,你将会看到三个线交替打印字母 'A'、'B' 和 'C',每个字母连续打印十次。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值