• 多线程面试题(Google)


    有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:

    A:1 2 3 4 1 2....

    B:2 3 4 1 2 3....

    C:3 4 1 2 3 4....

    D:4 1 2 3 4 1....

    请设计程序。

     

    我的思路是这样的:

    1、首先每个线程都只负责像一个文件句柄写入自己的id号,至于是向谁写,需要传参的,长得像这样:private void write(BufferedWriter bw)

    2、四个线程有一个公用锁lock,拿到锁的线程才能运行上述的write方法,每次都会从一个文件句柄List中取一个句柄出来,向其中写入id,每次都是取List.get(this.id)这个句柄

    3、句柄List每四次移一次,第一轮句柄顺序为[A B C D],第二轮就是[D A B C],这样每一轮线程取到的都是不一样的句柄

    4、什么是一轮:四个线程分别都向文件写入过内容,就是一轮,用now参数表示,now%4==0说明一轮结束,需要后移句柄

    5、定义一个flag为二进制的0000,第一个线程写入完毕就将最后一位置1,第二个线程写入完毕就将倒数第二位置1,以此类推,直到所有位置都被置为1,flags变为二进制1111,

    每次线程会判断,如果我的标志位置成了1,就不写入了

     

    以下是我的实现:

    public class InTurnWriteThread implements Runnable{

       

        public static LinkedList<BufferedWriter> bwList = new LinkedList<BufferedWriter>();

       

        // private static int[] flags = new int[]{0,0,0,0};

        private static int flags2 = 0;

       

        static{

            try {

                BufferedWriter bwa = new BufferedWriter(new FileWriter("F:/A.txt"));

                BufferedWriter bwb = new BufferedWriter(new FileWriter("F:/B.txt"));

                BufferedWriter bwc = new BufferedWriter(new FileWriter("F:/C.txt"));

                BufferedWriter bwd = new BufferedWriter(new FileWriter("F:/D.txt"));

                bwList.addLast(bwa);

                bwList.addLast(bwb);

                bwList.addLast(bwc);

                bwList.addLast(bwd);

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

       

        private static int now = 0;

       

        private final static String lock = "lock";

       

        private int id;

       

        public InTurnWriteThread(int id) {

            this.id = id;

        }

     

        @Override

        public void run() {

            int i = 8;

            while(i>0){

                synchronized (lock) {

                    // if(flags[this.id-1]==0){ 

                    if( (flags2 | (1<<(this.id-1)) ) > flags2){

                        this.write(bwList.get(this.id-1));

                        // flags[this.id-1]=1; 

                        flags2 = flags2|(1<<(this.id-1));

                        ++now;

                        --i;

                    }

                    if(now%4 == 0){

                        BufferedWriter tmp = bwList.removeLast();

                        bwList.addFirst(tmp);

                        // flags = new int[]{0,0,0,0}; 

                        flags2 = 0;

                    }

                }

            }

        }

       

        private void write(BufferedWriter bw){

            try {

                bw.write(id+" ");

                bw.flush();

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

     

        public static void main(String[] args) {

            Thread t1 = new Thread(new InTurnWriteThread(1));

            Thread t2 = new Thread(new InTurnWriteThread(2));

            Thread t3 = new Thread(new InTurnWriteThread(3));

            Thread t4 = new Thread(new InTurnWriteThread(4));

            t1.start();

            t2.start();

            t3.start();

            t4.start();

        }

    }

  • 相关阅读:
    读 Zepto 源码之内部方法
    读Zepto源码之代码结构
    vue-auto-focus: 控制自动聚焦行为的 vue 指令
    vue-lazy-render: 延迟渲染大组件,增强页面切换流畅度
    用vue实现模态框组件
    谷歌插件Image downloader开发之popup
    关于const
    Python线程指南(转自AstralWind)
    PyQt中的图形绘制
    sizeof和strlen之间的区别
  • 原文地址:https://www.cnblogs.com/liuzy2014/p/4800933.html
Copyright © 2020-2023  润新知