空中网笔试题

    张孝祥老师的CSDN有一篇博客介绍了空中网的线程笔试题,自己做了一下,第三题没有做出来,通过参考答案,也有了一些提升,后面会看张老师的视频将这篇文章补充完整。现阶段还没有深入学习线程的打算,学习平台的知识,深入了解Spring和Java基础知识是现阶段的重点,Maven貌似只能把电子书看完了。

注:http://developer.51cto.com/art/200911/162925.htm 很好的多线程基础知识介绍   

   

package com.zgy.thread;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;


/**
 * 空中网面试题.
 * 
 *
 * <pre>
 * date			modifier reason
 * 2013-5-3	zgy	     create
 * </pre>
 */
public class MultiThreadExam {

}


/**
 * 第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,
 * 请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象。
 * 
 *
 * <pre>
 * date			modifier reason
 * 2013-5-3	zgy	     create
 * </pre>
 */
class Test1 extends Thread{
    //依次代表生成的16个对象
    private static volatile String[] source = new String[16];
    //必须先让run方法执行inc(),形成秩序;如果先执行parseLog(xx)就会一秒输出4句一样的内容
    private static int num = -1;
    //同步方法,为什么静态有不同,静态修饰则inc方法属于Test1,否则属于对象即4个线程就有4个inc();
    //这样的话某个对象的inc方法的synchronized修饰符仅对这个对象有用
    //而我们需要的是对4个对象都有限制
    public static  synchronized void inc() {
        if(num > 15) {
            return;
        }
        num++;
    }
    
    public static void main(String[] args){
        //线程定义
        Thread[] thread = new Thread[4];
        for(int j=0;j<4;j++) {
            thread[j] = new Test1();
        }
        System.out.println("begin:"+(System.currentTimeMillis()/1000));
      
        /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。
                    修改程序代码,开四个线程让这16个对象在4秒钟打完。
        */
        for(int i=0;i<16;i++) {  //这行代码不能改动
            final String log = ""+(i+1);//这行代码不能改动
            //为字符串数组对象赋值
            source[i] = log;
        }
        //开启线程
        for(int j=0;j<4;j++) {
            thread[j].start();
        }
    }
    
    //parseLog方法内部的代码不能改动
    public static void parseLog(String log){
        System.out.println(log+":"+(System.currentTimeMillis()/1000));
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }       
    }
    
    @Override
    public void run() {
        try {
                //source[15]是最大值
                while(num < 15) {
                    inc();//必须先做,形成秩序
                    parseLog(source[num]);
                }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    
}


/**
 *  第二题:现成程序中的Test类中的代码在不断地产生数据,然后交给TestDo.doSome()方法去处理,
 *  就好像生产者在不断地产生数据,消费者在不断消费数据。请将程序改造成有10个线程来消费生成者产生的数据,
 *  这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要一秒才能处理完,
 *  程序应保证这些消费者线程依次有序地消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,
 *  下一个消费者是谁都可以,但要保证这些消费者线程拿到的数据是有顺序的。原始代码如下:
 * 
 *
 * <pre>
 * date			modifier reason
 * 2013-5-3	zgy	     create
 * </pre>
 */
class Test2 extends Thread{
    private static String[] source =new String[10];
    private static int num = -1;
    
  //同步方法
    public synchronized void inc() {
        num++;
    }
    @Override
    public void run() {
        try {
                    inc();
                    String output = TestDo.doSome(source[num]);
                    System.out.println(Thread.currentThread().getName()+ ":" + output);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //线程定义
        Thread[] thread = new Thread[10];
        for(int j=0;j<10;j++) {
            thread[j] = new Test2();
        }
        System.out.println("begin:"+(System.currentTimeMillis()/1000));
        for(int i=0;i<10;i++){  //这行不能改动
            String input = i+"";  //这行不能改动
            source[i] = input;
        }
      //开启线程
        for(int j=0;j<10;j++) {
            thread[j].start();
            thread[j].join();
        }
    }
}

//不能改动此TestDo类
class TestDo {
    public static String doSome(String input){
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String output = input + ":"+ (System.currentTimeMillis() / 1000);
        return output;
    }
}









/**
 * 第三题:现有程序同时启动了4个线程去调用TestDo.doSome(key, value)方法,
 * 由于TestDo.doSome(key, value)方法内的代码是先暂停1秒,然后再输出以秒为单位的当前时间值,
 * 所以,会打印出4个相同的时间值,如下所示:
  4:4:1258199615
  1:1:1258199615
  3:3:1258199615
  1:2:1258199615
   
   请修改代码,如果有几个线程调用TestDo.doSome(key, value)方法时,
   传递进去的key相等(equals比较为true),则这几个线程应互斥排队输出结果,
    即当有两个线程的key都是"1"时,它们中的一个要比另外其他线程晚1秒输出结果,如下所示:
  4:4:1258199615
  1:1:1258199615
  3:3:1258199615
  1:2:1258199616
   总之,当每个线程中指定的key相等时,这些相等key的线程应每隔一秒依次输出时间值(要用互斥),
   如果key不同,则并行执行(相互之间不互斥)。原始代码如下:
 * 
 *
 * <pre>
 * date			modifier reason
 * 2013-5-4	zgy	     create
 * </pre>
 */
//不能改动此Test类    
class Test3 extends Thread{
    private TestDo3 testDo;
    private String key;
    private String value;
    
    public Test3(String key,String key2,String value){
        this.testDo = TestDo3.getInstance();
        /*常量"1"和"1"是同一个对象,下面这行代码就是要用"1"+""的方式产生新的对象,
        以实现内容没有改变,仍然相等(都还为"1"),但对象却不再是同一个的效果*/
        this.key = key+key2; 
        this.value = value;
    }


    public static void main(String[] args) throws InterruptedException{
        Test3 a = new Test3("1"," ","1");
        Test3 b = new Test3("1"," ","2");
        Test3 c = new Test3("3"," ","3");
        Test3 d = new Test3("4"," ","4");
        Test3 e = new Test3("1"," ","2");
        System.out.println("begin:"+(System.currentTimeMillis()/1000));
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
    }
    
    public void run(){
        testDo.doSome(key, value);
    }
}

class TestDo3 {
    CopyOnWriteArrayList clist = new CopyOnWriteArrayList();
    List<String> test = new ArrayList<String>();
    private TestDo3() {}
    private static TestDo3 _instance = new TestDo3(); 
    public static TestDo3 getInstance() {
        return _instance;
    }

   
    public void doSome(Object key, String value) {
        Object lock = key;
        //添加失败说明是重复对象,返回false
        clist.addIfAbsent(lock);
        for(Iterator iterator = clist.iterator();iterator.hasNext();){
            Object o = iterator.next();
            if(lock.equals(o)){
                lock = o; // 同步的是lock这个对象,值重复的话就将对象指向同一个,否则每一个key都是不同的对象,synchronized失去意义
                break;
            }
        }
        synchronized(lock){
            try {
                Thread.sleep(1000);
                System.out.println(key + ":" + value + ":"
                        + (System.currentTimeMillis() / 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}



1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值