多线程打印数字

本文介绍了一种使用Java实现的多线程环境下控制打印顺序的方法。通过ReentrantLock和Condition等并发工具,确保了多个线程按指定顺序打印自然数,避免了线程间的竞争条件,展示了线程同步和锁的高级用法。
摘要由CSDN通过智能技术生成
package learning_java.Exercise;

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

public class MultiThreadPrinter {
    public static void main(String[] args) {
        int gap = 3;
        int end = 100;
        ExecutorService executor = Executors.newFixedThreadPool(gap);
        for (int i = 0; i < gap; i ++) {
            executor.execute(new PrinterWithLock(i, gap, end));
        }
        executor.shutdown();

    }

    private static class Printer implements Runnable{
        private static final Object LOCK = new Object();

        private int threadID;
        private final int GAP;
        private static int count = 0;
        private Printer(int id, int gap) {
            threadID = id;
            GAP = gap;
        }

        @Override
        public void run() {
            while (true) {
                synchronized (LOCK) {
                    while (count % GAP != this.threadID) {
                        if (count >= 101) break;
                        try {
                            LOCK.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                    if (count >= 101) break;
                    System.out.println("ThreadID:\t" + threadID + "\t:\t" + count);
                    ++count;
                    LOCK.notifyAll();
                }
            }
        }
    }

    private static class PrinterWithLock implements Runnable {
        // 需要注意,这里需要都为private static
        private static Lock lock = new ReentrantLock();
        // Condition若不是static的,则无法传递消息
        private static Condition isCurrentID = lock.newCondition();
        private final int threadID;
        private final int GAP;
        private static int count = 0;
        private final int END;

        private PrinterWithLock(int id, int gap, int end) {
            threadID = id;
            GAP = gap;
            END = end;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    lock.lock();
                    while (count % GAP != threadID) {
                        if (count > END) break;
                        isCurrentID.await();
                    }
                    if (count > END) break;
                    System.out.println("ThreadID:\t" + threadID + "\t:\t" + count);
                    ++count;
                    isCurrentID.signalAll();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }


//        @Override
//        public void run() {
//            while (true) {
//                try {
//                    lock.lock();
//                    while (count % 3 != this.threadID) {
//                        if (count >= 101) {
//                            break;
//                        }
//                        try {
//                            isCurrentID.await();
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }
//
//                    if (count >= 101) {
//                        break;
//                    }
//                    System.out.println("thread-" + this.threadID + ":" + count);
//                    count++;
//
//                    isCurrentID.signalAll();
//
//                } finally {
//                    lock.unlock();
//                }
//            }
//        }
    }

    private static class PrintThread2 implements Runnable {
        private static final ReentrantLock lock = new ReentrantLock();
        private static final Condition c = lock.newCondition();

        private static int count = 0; //作为计数,同时也作为资源;因为这道题目是自然数作为资源,所以正好可以公用;
        private Integer threadNo;

        public PrintThread2(Integer threadNo) {
            this.threadNo = threadNo;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    lock.lock();
                    while (count % 3 != this.threadNo) {
                        if (count >= 101) {
                            break;
                        }
                        try {
                            c.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    if (count >= 101) {
                        break;
                    }
                    System.out.println("thread-" + this.threadNo + ":" + count);
                    count++;

                    c.signalAll();

                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值