多线程笔试题

方便回忆,立个flag。有更好的解法希望不吝赐教。。。

package offer;

import java.util.Scanner;

/**
 * 多线程
 * 四个线程,A线程打印A,B线程打印B,C线程打印C,D线程打印D,要求按顺序打印ABCD,键盘输入打印的次数
 * 牛客网题目网址:https://www.nowcoder.com/practice/cd99fbc6154d4074b4da0e74224a1582?tpId=37&tqId=21272&tPage=3&rp=&ru=/ta/huawei&qru=/ta/huawei/question-ranking
 * Created by 怪兽 on 2018/3/12.
 */
public class pro5 {
    private static StringBuilder sb ;  //要写入的字符数组
    private int num;    //循环总的次数
    private int numCurrect; //当前循环次数
    private int index;  //线程下标

    public pro5(int num){
        this.num = num;
        index = 1;
        numCurrect = 0;
        sb = new StringBuilder(num * 4);
    }

    public void appandA(){
        synchronized (this){
            while(numCurrect < num){    //小于循环总数
                while (index != 1){ //非当前线程启动,一定要用while,以防止线程A再次获得对象锁----->注意notify唤醒线程是从wait方法之后的地方继续执行,而不是重新执行
                    try {
                        if(numCurrect == num )  //加条件退出,以销毁线程----->注意:并不是循环条件numCurrect < num就说明不会执行该段代码,因为是多线程,所以会存在数据的异步更新
                            break;
                        this.wait();    //释放对象锁
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(numCurrect == num )  //同理,加条件退出,以销毁线程
                    break;
                sb.append('A');
                index = 2;  //切换线程
                this.notifyAll();   //唤醒其他所有线程,该操作不会立即释放对象锁
            }
            System.out.println(sb.toString());  //循环次数结束,所有线程被销毁,输出打印sb
        }
    }

    public void appandB(){
        synchronized (this){
            while (numCurrect < num){
                while(index != 2){
                    try {
                        if(numCurrect == num )
                            break;
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(numCurrect == num )
                    break;
                sb.append('B');
                index = 3;
                this.notifyAll();
            }
        }
    }

    public void appandC(){
        synchronized (this){
            while (numCurrect < num){
                while(index != 3){
                    try {
                        if(numCurrect == num )
                            break;
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(numCurrect == num )
                    break;
                index = 4;
                sb.append('C');
                this.notifyAll();
            }
        }
    }

    public void appandD(){
        synchronized (this) {
            while (numCurrect < num) {
                while (index != 4) {
                    try {
                        if(numCurrect == num )
                            break;
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(numCurrect == num ) {
                    break;
                }
                index = 1;
                sb.append('D');
                numCurrect++;
                this.notifyAll();
            }
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            int num = scanner.nextInt();
            pro5 pro5 = new pro5(num);

            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() { pro5.appandA(); }
            });
            thread1.start();
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    pro5.appandB();
                }
            });
            thread2.start();
            Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    pro5.appandC();
                }
            });
            thread3.start();
            Thread thread4 = new Thread(new Runnable() {
                @Override
                public void run() {
                    pro5.appandD();
                }
            });
            thread4.start();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
#笔试题目#
全部评论
public static void main(String[] args) throws InterruptedException {     final int PRINT_TIMES = 3;     final int THREADS_NUMBER = 4;     CountDownLatch latch = new CountDownLatch(THREADS_NUMBER);     Object[] locks = new Object[THREADS_NUMBER];     for (int i = 0; i < locks.length; i++) {         locks[i] = new Object();     }     for (int i = 0; i < locks.length; i++) {         new MyThread(locks[i], locks[(i + 1) % locks.length],                      PRINT_TIMES, (char) ('A' + i), latch)                 .start();     }     // 确认所有子线程已处于等待状态     latch.await();     synchronized (locks[0]) {         locks[0].notify();     } } private static class MyThread extends Thread {     final Object lock;     final Object nextLock;     int printTime;     char c;     CountDownLatch latch;     MyThread(Object lock, Object nextLock, int printTime,              char c, CountDownLatch latch) {         this.lock = lock;         this.nextLock = nextLock;         this.printTime = printTime;         this.latch = latch;         this.c = c;     }     public void run() {         synchronized (lock) {             for (int i = 0; i < printTime; i++) {                 latch.countDown();                 try {                     // 等待当前线程被唤醒                     lock.wait();                 } catch (InterruptedException e) {                     e.printStackTrace();                 }                 // 输出并唤醒下一线程                 System.out.println(c);                 synchronized (nextLock) {                     nextLock.notify();                 }             }         }         synchronized (nextLock) {             nextLock.notify();         }     } }
1 回复 分享
发布于 2018-03-18 12:01
Join
点赞 回复 分享
发布于 2018-03-14 23:35
谢谢大家,我再来学习一下。^_^
点赞 回复 分享
发布于 2018-03-16 18:08
这个面试遇到过。用ReentrantLock 的condition就行啦。再配合一个int类型的flag
点赞 回复 分享
发布于 2018-03-16 02:27
大三的课程作业。。写几个自旋锁就行 用四个变量控制
点赞 回复 分享
发布于 2018-03-15 00:26
可以搞几个重入锁,a打印完唤醒b b打印出来唤醒c 以此类推 。没打印完前阻塞
点赞 回复 分享
发布于 2018-03-15 00:20
同楼上,第一想法就是join 或者countdownlatch,cyclicbarrier?
点赞 回复 分享
发布于 2018-03-14 23:57

相关推荐

仁者伍敌:难怪小公司那么挑剔,让你们这些大佬把位置拿了
点赞 评论 收藏
分享
每晚夜里独自颤抖:要求太多的没必要理
点赞 评论 收藏
分享
评论
点赞
22
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务