问题一:
一个多线程的问题,用三个线程,顺序打印字母A-Z,输出结果是1A 2B 3C 1D 2E…打印完毕最后输出一个Ok。
代码一:
public class forCharacter {
private static char c = 'A';
private static int i = 0;
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
public void run() {
int threadId = Integer.parseInt(Thread.currentThread().getName());
while(i < 26){
if(i % 3 == threadId - 1){
System.out.println("线程id:" + threadId + " " + (char)c++);
i++;
if(i == 26)
System.out.println("哈哈,祝拿到offer!");
}
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
};
Thread t1 = new Thread(r, "1");
Thread t2 = new Thread(r, "2");
Thread t3 = new Thread(r, "3");
t1.start();
t2.start();
t3.start();
}
}
但是代码一存在问题:这样写的话,可能会造成资源浪费,所以我们可以通过加锁进行限制,但是加锁后,因为sleep不会释放锁,会导致其他线程无法获得执行机会。因此需要配合wait和notifyAll。
代码二:
public class forCharacter {
/*
* Description:一个多线程的问题,用三个线程,顺序打印字母A-Z,输出结果是1A 2B 3C 1D 2E...打印完毕最后输出一个Ok
* Author:ZhangRuirui
* Date:2018/05/25
* Email:zhangrrbugfree@163.com
*/
private static char c = 'A';// 必要的时候声明为volatile类型的
private static int i = 0;
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
public void run() {
synchronized (this) {
try {
int threadId = Integer.parseInt(Thread.currentThread().getName());
System.out.println("当前线程id:" + threadId + " ");
while (i < 26) {
if (i % 3 == threadId - 1) {
System.out.println("线程id:" + threadId + " " + (char) c++);
i++;
if (i == 26)
System.out.println("哈哈,祝拿到offer!");
notifyAll();// 唤醒其他线程
} else {
wait();// 阻塞其他线程
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t1 = new Thread(r, "1");
Thread t2 = new Thread(r, "2");
Thread t3 = new Thread(r, "3");
t1.start();
t2.start();
t3.start();
}
}
输出:
当前线程id:1
线程id:1 A
当前线程id:2
线程id:2 B
当前线程id:3
线程id:3 C
线程id:1 D
线程id:2 E
线程id:3 F
线程id:1 G
线程id:2 H
线程id:3 I
线程id:1 J
线程id:2 K
线程id:3 L
线程id:1 M
线程id:2 N
线程id:3 O
线程id:1 P
线程id:2 Q
线程id:3 R
线程id:1 S
线程id:2 T
线程id:3 U
线程id:1 V
线程id:2 W
线程id:3 X
线程id:1 Y
线程id:2 Z
哈哈,祝拿到offer!
问题二:(快手)
一个多线程的问题,用五个线程,顺序打印数字1~无穷大,其中每5个数字为1组,如下:其中id代表线程的id
id 1 2 3 4 5
no 1 2 3 4 5
no 6 7 8 9 10
no 11 12 13 14 15
no .. .. .. .. ..
代码:
public class forCharacter2 {
/*
* Description:一个多线程的问题,用五个线程,顺序打印数字1~无穷大,其中每5个数字为1组
* Author:ZhangRuirui
* Date:2018/05/25
* Email:zhangrrbugfree@163.com
*/
private static volatile int orderNum = 1;// 必要的时候声明为volatile类型的
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
synchronized (this) {
try {
int threadId = Integer.parseInt(Thread.currentThread().getName());
while (true) {
if (orderNum % 5 == threadId || orderNum % 5 == 0) {
if (orderNum % 5 == 0)
System.out.println("threadid = " + 5 + " " + orderNum++);
else
System.out.println("threadid = " + threadId + " " + orderNum++);
Thread.sleep(1000);// 为了执行效果看的更清楚
notifyAll();
} else {
wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t1 = new Thread(r, "1");
Thread t2 = new Thread(r, "2");
Thread t3 = new Thread(r, "3");
Thread t4 = new Thread(r, "4");
Thread t5 = new Thread(r, "5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
输出:
threadid = 1 1
threadid = 2 2
threadid = 3 3
threadid = 4 4
threadid = 5 5
threadid = 1 6
threadid = 2 7
threadid = 3 8
threadid = 4 9
threadid = 5 10
threadid = 1 11
threadid = 2 12
threadid = 3 13
threadid = 4 14
threadid = 5 15
threadid = 1 16
threadid = 2 17
//下面死循环不断输出