java多线程--几个多线程面试题小结

小编 2026-07-15 阅读:719 评论:0
  自学了一段时间的多线程知识,尝试了做了几个编程题,发现想象中很简单的功能,自己真写起来要花费...

  自学了一段时间的多线程知识,尝试了做了几个编程题,发现想象中很简单的功能,自己真写起来要花费远超自己想象的功夫,知识点易学,不易用啊.

面试题1:编写程序实现,子线程循环10次,接着主线程循环20次,接着再子线程循环10次,主线程循环20次,如此反复,循环50次.

package com.wang.reflect;//编写功能类,实现子线程和主线程的功能class Function{    private boolean flag=false;    //子线程要实现的功能    public synchronized void sub(){        while(flag){            try {                this.wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }                       for(int i=0;i<10;i++){            //for循环内定义子线程的功能,这里简单的假设为打印一句话,主线程同理            System.out.println("sub"+i);        }                flag=true;        this.notify();    }    //主线程要实现的功能    public synchronized void main(){        while(!flag){            try {                this.wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        for(int i=0;i<20;i++){            System.out.println("main"+i);        }                flag=false;        this.notify();    }    }public class Demo01 {      public static void main(String[] args) {         final Function f=new Function();        new Thread(                new Runnable(){                    @Override                    public void run() {                        for(int i=0;i<50;i++){                            f.sub();                        }                    }                                }                ).start();                for(int i=0;i<50;i++){            f.main();        }    }}

  JDK1.5以后,出现了Lock和condition,Lock类似于synchronized功能,用来进行线程同步,Condition功能类似于Object类中的wait和notify方法,用于线程间的通信.上面的代码可以用Lock和Condition来改进,如下:

 

package com.wang.reflect;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;//编写功能类,实现子线程和主线程的功能class Function{    private boolean flag=false;        Lock lock=new ReentrantLock();    Condition con=lock.newCondition();    //子线程要实现的功能    public  void sub(){        lock.lock();        try {                        while(flag){                try {                    con.await();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }                                    for(int i=0;i<10;i++){                //for循环内定义子线程的功能,这里简单的假设为打印一句话,主线程同理                System.out.println("sub"+i);            }                        flag=true;            con.signal();        } finally{            lock.unlock();        }    }    //主线程要实现的功能    public synchronized void main(){        lock.lock();        try {            while (!flag) {                try {                    con.await();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            for (int i = 0; i < 20; i++) {                System.out.println("main" + i);            }            flag = false;            con.signal();        } finally{            lock.unlock();        }    }    }public class Demo01 {            public static void main(String[] args) {         final Function f=new Function();        new Thread(                new Runnable(){                    @Override                    public void run() {                        for(int i=0;i<50;i++){                            f.sub();                        }                    }                                }                ).start();                for(int i=0;i<50;i++){            f.main();        }    }}

 

 

 

面试题2:设计四个线程,其中两个线程每次对变量i加1,另外两个线程每次对i减1.

package com.wang.reflect;/** * 设计四个线程,其中两个线程每次对变量i加1,另外两个线程每次对i减1. * @author Administrator * */public class Demo02 {    private int  i=0;    public static void main(String[] args) {        Demo02 demo=new Demo02();        Add add = demo.new Add();        Sub sub = demo.new Sub();        for(int i=1;i<=2;i++){            new Thread(add,"线程"+i).start();            new Thread(sub,"线程"+i).start();        }    }            //定义一个内部类Add,实现功能每次对i加一    class Add implements Runnable{        @Override        public void run() {            for(int i=0;i<10;i++){                addOne();                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }            }    //定义一个内部类Sub,实现功能每次对i减1    class Sub implements Runnable{        @Override        public void run() {            for(int i=0;i<10;i++){            subOne();            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }            }        }            }        public synchronized void addOne() {        i++;        System.out.println(Thread.currentThread().getName()+"加一的值为:"+i);    }    public synchronized void subOne(){        i--;        System.out.println(Thread.currentThread().getName()+"减一的值为:"+i);    }}

面试题3:自己编写代码,实现生产者-消费者模型功能.内容自由发挥,只需要表达思想.

  代码中,自定义一个学生类,有name和age属性,属于共享对象,生产者负责为studnet对象赋值,消费者负责打印出student对象的name和age的值,当生产者赋值完以后通知消费者来打印,消费者打印完以后,通知生产者重新设置.

package com.wang.reflect;//学生实体类作为共享资源class Student {    private String name;// 姓名    private int age;// 年龄    boolean flag;// 标记变量,判断当前学生对象是否已创建赋值好    //生产者的功能  ,为studnet对象赋值    public synchronized void set(String name, int age) {        if (this.flag) {            try {                this.wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        this.name = name;        this.age = age;        this.flag = true;        this.notify();    }    //消费者的功能,打印sutdent对象的内容    public synchronized void get() {        if (!this.flag) {            try {                this.wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        System.out.println(name + ":::" + age);        this.flag = false;        this.notify();    }}// 模拟生产者线程类class SetStudent implements Runnable {    // 共享资源s    private Student s;    private int x = 0;    public SetStudent(Student s) {        this.s = s;    }    @Override    public void run() {        while (true) {            if (x % 2 == 0) {                s.set("郭靖", 27);            } else {                s.set("黄蓉", 18);            }            x++;        }    }}// 模拟消费者线程类class GetStudent implements Runnable {    // 共享资源s    private Student s;    public GetStudent(Student s) {        this.s = s;    }    @Override    public void run() {        while (true) {            s.get();        }    }}// 测试类public class Demo03{    public static void main(String[] args) {        Student s = new Student();        SetStudent ss = new SetStudent(s);        GetStudent gs = new GetStudent(s);        Thread t1 = new Thread(ss, "生产者");        Thread t2 = new Thread(gs, "消费者");        t1.start();        t2.start();    }}

面试题4: 现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象。

原始代码如下:

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();            }                }            }

改写代码如下:

package com.wang.reflect;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;public class Demo03 {        public static void main(String[] args){        //定义一个线程共享的队列容器,可以使得数据由队列的一端输入,从另外一端输出        final BlockingQueue<String> queue=new ArrayBlockingQueue<String>(16);        for(int i=0;i<4;i++){            new Thread(new Runnable(){                @Override                public void run() {                    while(true){                        try {                            parseLog(queue.take());                        } catch (InterruptedException e) {                            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) {                        e.printStackTrace();                    }            }        }    }        //parseLog方法内部的代码不能改动    public static void parseLog(String log){        System.out.println(log+":"+(System.currentTimeMillis()/1000));                try {            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }            }    }

 

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表