多线程题目练习
2020-08-30 本文已影响0人
HannahLi_9f1c
周末有空,看了看多线程的一些练习题,然后试着写了写,感觉到实践还是很重要,光学习理论知识是远远不够的,还需要多加练习,才能更深刻理解多线程的奥妙,真的是非常有趣!
- 给定一个数组,一个线程打印奇数,另一个线程打印偶数。按照数组原始顺序打印。这里的思路是用了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();
}
}
}
}
}
- 使用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();
}
}
}
}
}