2种方式(线程间通信/互斥锁)实现两个线程,一个线程打印1-52,另一个线程打印字母A-Z,打印顺序为12A34B56C......5152Z

//2019/06/13 本周HT面试遇到的问题,答得不是很好,自己重新做一下。面试只需要写出线程间通信的方式,
//我当时大致知道思路,因为之前看过马士兵老师的多线程视频,但是代码写出来估计编译都是报错的。

//线程通信方式
public class ThreadTwo {

   //内部静态类,类去实现Runnable接口,obj通过构造方法,是希望这两个方法被一个参数锁住
public static class PrintABC implements Runnable{
Object o = null;

public PrintABC(Object o) {
this.o = o;
}

@Override
public void run() {
synchronized (o){
char ch = 'A';
for(int i=0;i<26;i++) {
            //ascii码吧
System.out.print((char) (ch + i));
            //之前这个写在了wait()方法后面,导致一直睡下去,无法唤醒了
o.notifyAll();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}
}

private static class Print123 implements Runnable{

Object o = null;

public Print123(Object o) {
this.o = o;
}

@Override
public void run() {
synchronized (o) {
for(int i=1;i<=52;i++) {
System.out.print(i);
if (i % 2 == 0) {
o.notifyAll();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}
}
}

public static void main(String[] args) {
     //同一把锁
Object o = new Object();
new Thread(new Print123(o)).start();
new Thread(new PrintABC(o)).start();
}

}

//互斥锁方式
public class ThreadTwoLock {

static class PrintAll{

Lock lock = new ReentrantLock();
Condition conChar = lock.newCondition();
Condition conNum = lock.newCondition();

boolean flag = true;

public void printABC(){
        //二话不说,方法一上来先锁上
lock.lock();

try {

for (int i = 0; i < 26; i++) {
            //每次打印之前判断自己还能不能打印,flag==true表示打印字母的要等下,让打印数字的来
if (flag) {
conChar.await();
}
char a = 'A';
System.out.print((char) (a + i));
            //打印了一个字母,让当前打印字母的线程停下,flag=true
flag=true;
            //唤醒打印数字的线程
conNum.signal();

}
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
            //释放锁
lock.unlock();
}

}

public void print123(){

lock.lock();

try {

for (int i = 1; i <= 52; i++) {
if(!flag) {
conNum.await();
}
System.out.print(i);
if (i % 2 == 0) {
flag = false;
conChar.signal();

}
}

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

public static void main(String[] args) {
final PrintAll pa = new PrintAll();
    //main方法里就负责创建和启动线程,别的啥也不做
new Thread(()->{
pa.printABC();
}).start();
new Thread(()->{
pa.print123();
}).start();

}
}

运行结果:
12A34B56C78D910E1112F1314G1516H1718I1920J2122K2324L2526M2728N2930O3132P3334Q3536R3738S3940T4142U4344V4546W4748X4950Y5152Z

上一篇:Android百分比布局支持库(android-percent-support)


下一篇:.net基础学java系列(二)IDE 之 插件