多线程题目练习

2020-08-30  本文已影响0人  HannahLi_9f1c

周末有空,看了看多线程的一些练习题,然后试着写了写,感觉到实践还是很重要,光学习理论知识是远远不够的,还需要多加练习,才能更深刻理解多线程的奥妙,真的是非常有趣!

  1. 给定一个数组,一个线程打印奇数,另一个线程打印偶数。按照数组原始顺序打印。这里的思路是用了Lock中的Condition条件变量,定义两个线程。奇数线程打印奇数,并且判断当前是奇数时,打印并且唤醒偶数线程,如果当前不是奇数,那么当前线程等待。这里一值卡在忘记加了最外层的判断,也就是i<num.length,导致打印了两个数就结束了。
public class Main {
    private static Lock lock = new ReentrantLock();
    private static Condition odd = lock.newCondition();
    private static Condition even = lock.newCondition();
    static    int [] num ;
    private static int i = 0;
    public static void main(String [] args) {
        num = new int[]{1,2,3,4,5,6,7,8,9,10};
        Thread odd = new Thread(new OddRunnable());
        odd.start();
        Thread even = new Thread(new EvenRunnable());
        even.start();

    }
    static class OddRunnable implements Runnable{

        @Override
        public void run() {
            while(i<num.length) {
                lock.lock();
                try {

                    while (i < num.length && num[i] % 2 == 1) {
                        System.out.println(Thread.currentThread().getName() + num[i]);
                        i++;
                        even.signal();
                    }
                    odd.await();


                    //lock.unlock();
                    //odd.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
    static class EvenRunnable implements Runnable{

        @Override
        public void run() {
            while(i<num.length) {
                lock.lock();
                try {
                    while (i < num.length && num[i] % 2 == 0) {
                        System.out.println(Thread.currentThread().getName() + num[i]);
                        i++;
                        odd.signal();
                    }
                    even.await();


                    //even.await();


                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

}

  1. 使用N个线程,交替打印数组。这里对于N个线程,初始化N个条件变量,当前线程打印完之后,就唤醒它的下一个线程。
public class Printer {
    private static  int i = 0;
    private static int[]a = new int[100];
    private static Lock lock = new ReentrantLock();
    //private static Condition condition = lock.newCondition();
    private static int N = 10;
    private static Condition conditions[] = new Condition[N];
    public static void main(String[] args) {

        IntStream.range(0,100).forEach(i->a[i] = i);
        IntStream.range(0,N).forEach(i->conditions[i] = lock.newCondition());
        IntStream.range(0,N).forEach(i->new Thread(new PrinterRunnable(i)).start());

    }
    static class PrinterRunnable implements Runnable{
        int num;
        public PrinterRunnable(int num) {
            this.num = num;
        }
        @Override
        public void run() {
            while(i<a.length) {
                lock.lock();
                try {
                    if ((i)%N == num){
                        System.out.println(Thread.currentThread().getName() + " " + a[i]);
                        i++;
                        conditions[(num+1)%N].signal();
                    }else {
                        conditions[num].await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读