通过n个线程顺序打印26个英文字母

通过n个线程顺序打印26个英文字母,例如 n=3 则输出:
thread0: a
thread1: b
thread2: c
thread0: d

方案一:轮询

多个线程不断轮询是否是该线程执行任务。因为线程要不断轮循,所以效率较低。

答案

import java.util.*;

/**
 * n个线程顺序打印英文字母
 */
class Solution {
    //用于更换线程
    private volatile static int current = 0;
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int in = scanner.nextInt();
        int max = 25;
        for (int i = 0; i < in; i++) {
            new Thread(new Print(in, i, max), "Thread:" + i).start();
        }
    }


    static class Print implements Runnable {
        //线程总数
        private final int num;
        //当前线程号
        private final int no;
        //与current配合更换线程
        private final int max;

        public Print(int num, int no, int max) {
            this.num = num;
            this.no = no;
            this.max = max;
        }

        @Override
        public void run() {
            while (current <= max) {
                if (current % num == no) {
                    synchronized (Print.class) {
                        if (current <= max) {
                            System.out.println(Thread.currentThread().getName() + ":" + (char)(97 + current));
                            current++;
                        }
                    }
                }
            }
        }
    }

}

测试

Thread:0:a
Thread:1:b
Thread:2:c
Thread:0:d
Thread:1:e
Thread:2:f
Thread:0:g
Thread:1:h
Thread:2:i
Thread:0:j
Thread:1:k
Thread:2:l
Thread:0:m
Thread:1:n
Thread:2:o
Thread:0:p
Thread:1:q
Thread:2:r
Thread:0:s
Thread:1:t
Thread:2:u
Thread:0:v
Thread:1:w
Thread:2:x
Thread:0:y
Thread:1:z

方案二:condition

对于ReentrantLock,里面提供了newCondition方法,对于每一个线程,其await的时候都可以关联一个Condition对象,别的线程也可以通知这个condition对象进行唤醒。因为每个线程拿到锁以后会做判断,不是他的任务直接就进入等待状态挂起了,所以效率好一些。注意最后判断线程是否要进行挂起的条件,如果之后没有它要进行的任务就不要挂起了,否则最后进程可能执行不完。

import java.util.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * n个线程顺序打印英文字母
 */
class Solution {
    //用于更换线程
    private static int current = 0;
    private static final ReentrantLock lock = new ReentrantLock();
    private static final ArrayList<Condition> conditions = new ArrayList<>();

    public static void main(String[] args) {
        //输入的数必须大于1
        Scanner scanner = new Scanner(System.in);
        int in = scanner.nextInt(); 
        int max = 25;

        //为每个线程设置等待条件
        for (int i = 0; i < in; i++) {
            conditions.add(lock.newCondition());
        }

        for (int i = 0; i < in; i++) {
            new Thread(new Print(in, i, max), "Thread:" + i).start();
        }
    }


    static class Print implements Runnable {
        //线程总数
        private final int num;
        //当前线程号
        private final int no;
        //与current配合更换线程
        private final int max;

        public Print(int num, int no, int max) {
            this.num = num;
            this.no = no;
            this.max = max;
        }

        @Override
        public void run() {
            while (current <= max) {
                try {
                    lock.lock();
                    if (current % num == no) {
                        if (current <= max) {
                            System.out.println(Thread.currentThread().getName() + ":" + (char)(97 + current));
                            current++;
                        }
                        conditions.get((no + 1) % num).signal();
                        if (current < max && max - current >= num) {
                            conditions.get(no).await();
                        }
                    } else {
                        if (current < max && max - current >= num) {
                            conditions.get(no).await();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }

        }
    }
}


测试:

Thread:0:a
Thread:1:b
Thread:2:c
Thread:3:d
Thread:4:e
Thread:0:f
Thread:1:g
Thread:2:h
Thread:3:i
Thread:4:j
Thread:0:k
Thread:1:l
Thread:2:m
Thread:3:n
Thread:4:o
Thread:0:p
Thread:1:q
Thread:2:r
Thread:3:s
Thread:4:t
Thread:0:u
Thread:1:v
Thread:2:w
Thread:3:x
Thread:4:y
Thread:0:z

Process finished with exit code 0

posted @ 2022-03-23 15:26  imissinstagram  Views(198)  Comments(0)    收藏  举报