java线程面试题 (一)

来源:互联网 发布:步惊云软件教学系统 编辑:程序博客网 时间:2024/06/06 09:25

第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象。
方法的注意: 大家只要将上面任何一题的完整代码复制到eclipse中的某个工程的src目录下,就可以自动生成包名和文件名,运行该程序就可以观察到程序修改前的运行效果。
源代码:

package cn.itcast.thread;    public class Test {        public static void main(String[] args){            System.out.println("begin:"+(System.currentTimeMillis()/1000));            /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。            修改程序代码,开四个线程让这16个对象在4秒钟打完。            */            for(int i=0;i<16;i++){  //这行代码不能改动                final String log = ""+(i+1);//这行代码不能改动                {                        Test.parseLog(log);                }            }        }        //parseLog方法内部的代码不能改动        public static void parseLog(String log){            System.out.println(log+":"+(System.currentTimeMillis()/1000));            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }               }    }

结果

begin:14966660611:14966660612:14966660623:14966660634:14966660645:14966660656:14966660667:14966660678:14966660689:149666606910:149666607011:149666607112:149666607213:149666607314:149666607415:149666607516:1496666076

修改后,BlockingQueue的用法
当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空队列进行出队列操作时,它将会被阻塞,除非有另一个线程进行了入队列操作。
BlockingQueue参考链接

    package read;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;public class Test {        public static void main(String[] args){            BlockingQueue<String> queue= new ArrayBlockingQueue<String>(16);            for(int i=0;i<4;i++){                new Thread(new Runnable() {                    @Override                    public void run() {                        // TODO Auto-generated method stub                        while(true){                            try {                                String log=queue.take();                                parseLog(log);                            } catch (InterruptedException e) {                                // TODO Auto-generated catch block                                e.printStackTrace();                            }                        }                    }                }).start();            }            System.out.println("begin:"+(System.currentTimeMillis()/1000));            /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。            修改程序代码,开四个线程让这16个对象在4秒钟打完。            */            for(int i=0;i<16;i++){  //这行代码不能改动                final String log = ""+(i+1);//这行代码不能改动                {                    try {                        queue.put(log);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                        //Test.parseLog(log);                }            }        }        //parseLog方法内部的代码不能改动        public static void parseLog(String log){            System.out.println(log+":"+(System.currentTimeMillis()/1000));            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }               }    }

结果

begin:14966673261:14966673262:14966673263:14966673264:14966673265:14966673276:14966673277:14966673278:14966673279:149666732810:149666732811:149666732812:149666732813:149666732914:149666732915:149666732916:1496667329