用两个线程,一个输出字母,一个输出数字,交替输出A1B2C3D4…Z26
这道题主要是考察大家对线程的掌握程度以及正确操控线程。
第一种写法:
/**
* 用两个线程,一个输出字母,一个输出数字,交替输出。1A2B3C4D5E6F7G
*/
public class ThreadDemo1 {
private static final String[] charArr = new String[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","V","W","X","Y","Z"};
private static final int[] numArr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26};
private static Thread thread1 = null;
private static Thread thread2 = null;
public static void main(String[] args) throws Exception {
thread1 = new Thread(()->{
for (String c : charArr) {
System.out.print(c);
// 打印完让线程2执行
LockSupport.unpark(thread2);
// 线程1等待
LockSupport.park(thread1);
}
});
thread2 = new Thread(()->{
for (int n : numArr) {
// 上来线程2先等待
LockSupport.park(thread2);
System.out.print(n);
// 输出完唤醒线程1,让线程1执行
LockSupport.unpark(thread1);
}
});
thread1.start();
thread2.start();
}
}
第二种写法:
public class ThreadDemo2 {
private static final String[] charArr = new String[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","V","W","X","Y","Z"};
private static final int[] numArr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26};
private static Thread thread1 = null;
private static Thread thread2 = null;
public static void main(String[] args) throws Exception {
Object o = new Object();
thread1 = new Thread(()->{
for (String c : charArr) {
synchronized (o) {
// 只有拿到o这把锁才可以打印,由于先启动线程1,所以线程1先拿到这把锁
System.out.print(c);
try {
// 唤醒任意一个线程,让它去竞争锁
o.notify();
// 释放锁
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread2 = new Thread(()->{
for (int n : numArr) {
synchronized (o) {
// 当第一个线程释放锁后 线程2拿到锁
System.out.print(n);
try {
// 叫醒队列里任意一个线程去竞争锁
o.notify();
// 如果是最后一个元素就不用释放锁去排队了
if (n != numArr.length) {
// 释放锁
o.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
}
}
第三种写法:
public class ThreadDemo3 {
private static final String[] charArr = new String[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","V","W","X","Y","Z"};
private static final int[] numArr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26};
private static Thread thread1 = null;
private static Thread thread2 = null;
// 定义两个线程开关
enum Run{T1, T2}
// 定义线程1先执行
// volatile让线程保持可见性
static volatile Run run = Run.T1;
public static void main(String[] args) throws Exception {
thread1 = new Thread(()->{
for (String c : charArr) {
// 如果是线程2运行,则空转等待
while (run == Run.T2) {}
System.out.print(c);
// 让线程2运行
run = Run.T2;
}
});
thread2 = new Thread(()->{
for (int n : numArr) {
// 如果是线程1执行,空转等待
while (run == Run.T1) {}
System.out.print(n);
// 让线程1运行
run = Run.T1;
}
});
thread1.start();
thread2.start();
}
}
第四种写法:
public class ThreadDemo4 {
private static final String[] charArr = new String[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","V","W","X","Y","Z"};
private static final int[] numArr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26};
private static Thread thread1 = null;
private static Thread thread2 = null;
/**
* 定义两个q,他们的特点就是手递手传递,队列里必须有内容,没有内容就会阻塞
*/
static BlockingQueue<String> q1 = new ArrayBlockingQueue(1);
static BlockingQueue<String> q2 = new ArrayBlockingQueue(1);
public static void main(String[] args) throws Exception {
thread1 = new Thread(()->{
for (String c : charArr) {
System.out.print(c);
try {
// 给队列2放点东西,这样队列2就不阻塞了
q2.put("ok");
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
// 去队列1取东西,没东西就在这阻塞
q1.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread2 = new Thread(()->{
for (int n : numArr) {
try {
// 上队列2里取东西,如果没有东西,就阻塞,不往下执行
q2.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(n);
try {
// 往队列1里放东西,队列1就不阻塞了
q1.put("ok");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
}
}