前面针对多线程相关知识点进行了学习,那么我们来来看看常见的面试题:

1. 空中网面试题1  

package com.kongzhongwang.interview;  

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; //myeclipse强大功能:将代码直接复制到项目的src路径下可以自动相应生成包名和类名
/**
*
* 空中网面试题1:现有程序代码模拟产生16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加四个线程去调用
* parseLog()方法来分头打印这16个日志对象,程序只需运行4秒即可打印完这些日志对象。
* 考察新技术BlockingQueue
*/ public class ReadLog {
public static void main(String[] args) { /*此处有一个巧合:这里ArrayBlockingQueue<String>(1)和ArrayBlockingQueue<String>(16)
* 达到的效果一样,并且前者产生的数据组合更整齐;目前推测是巧合,希望大牛发现因果了告知一声
*/
final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
for (int i = 0; i < 4; i++) {
new Thread(new Runnable() {
public void run() {
while (true) {
try {
String log = queue.take();
parseLog(log);
} 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); // 这行代码不能改动
{
// ReadLog.parseLog(log);
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();
}
}
}
2. 空中网面试题2 package com.kongzhongwang.interview; import java.util.concurrent.Semaphore;
import java.util.concurrent.SynchronousQueue; /**
* 空中网面试题2: 现成程序中的Test类中的代码在不断地产生数据,然后交给TestDo.doSome()方法去处理;
* 这就好像是生产者在不断地产生数据,消费者在不断地消费数据。请将程序改造成有10个线程来消费生产者产生的数据,
* 这些消费者都调用TestDo.doSome()方法去处理,固每个消费者都需要1秒才能处理完,程序应该保证这些
* 消费者线程依次有序的消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,下一个消费者是谁都可以, 但要保证消费者拿到的数据是有顺序的。
*/
public class Test { public static void main(String[] args) { //使用semaphore信号灯相当于上一个lock锁
final Semaphore semaphore = new Semaphore(1);
//新的队列方式
final SynchronousQueue<String> queue = new SynchronousQueue<String>();
for(int i=0;i<10;i++){
new Thread(new Runnable() { @Override
public void run() {
try {
semaphore.acquire();
String input = queue.take();
String output = TestDo.doSome(input);
System.out.println(Thread.currentThread().getName() + ":" + output);
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
System.out.println("begin:" + (System.currentTimeMillis() / 1000)); for (int i = 0; i < 10; i++) { // 这行代码不能改动
String input = i + ""; // 这行代码不能改动
try {
queue.put(input);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} // TestDo类不能动
class TestDo { public static String doSome(String input) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
String output = input + ":" + (System.currentTimeMillis() / 1000);
return output;
} }
3.空中网面试题3 package com.kongzhongwang.interview; import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList; public class Tests extends Thread { /**
* 空中网面试题3: 现有程序同时启动了四个线程去调用TestDo.doSome(key,value)方法;
* 由于TestsDo.doSome(key,value)方法内的代码是先暂停1秒,然后再输出以秒为单位的当前时间值,
* 所以会打印出四个相同的时间值,如下所示:4:4 1258199615 1:1 1258199615 3:3 1258199615 2:2
* 1258199615 ;请修改代码,如果有几个线程调用TestDo.doSome(key,value)方法时;
* 传递进去的key值相等(equals比较为true),则这几个线程应互斥输出结果,即当有两个线程的key都为1时,
* 它们中的一个要比其他线程晚一步输出结果,如下所示:4:4 1258199615 1:1 1258199615 3:3 1258199615 1:2
* 1258199616 ;总之每个线程中指定的key相等时;这些相等的线程应每隔1秒输出时间值(要用互斥),
* key不同,则并行执行(相互之间不互斥)
*/ private TestsDo testDo;
private String key;
private String value; private Tests(String key, String key2, String value) {
this.testDo = TestsDo.getInstance();
/*
* 常量“1”和“1”是同一个对象,下面这行代码就是要用“1”+“”的方式产生新的对象;
* 以实现内容没有改变,仍然相等(都还为“1”),但对象却不再是同一个的效果
*/
this.key = key + key2;
/*
* a = "1"+"";
* b = "2"+"";
* a和b是同一个对象,因为编译器在执行之前就会将其优化为 a=“1”;
* 但是this.key = key + key2;这句,编译器不会给你优化,
* 因为你是属性变量,编译器不知道你将来要传入什么值
*/
this.value = value;
} public static void main(String[] args) { Tests a = new Tests("1", "", "1");
Tests b = new Tests("1", "", "2");
Tests c = new Tests("3", "", "3");
Tests d = new Tests("4", "", "4");
System.out.println("begin:" + (System.currentTimeMillis() / 1000));
a.start();
b.start();
c.start();
d.start();
} public void run() {
testDo.doSome(key, value);
}
} class TestsDo {
private TestsDo() {}
private static TestsDo _instance = new TestsDo();
public static TestsDo getInstance() {
return _instance;
}
//传统写法,没有考虑到线程并发问题
// private ArrayList keys = new ArrayList();
private CopyOnWriteArrayList keys = new CopyOnWriteArrayList();
public void doSome(Object key,String value){
Object o = key;
if(! keys.contains(o)){
keys.add(o);
}else{
//迭代的过程中不能进行其他操作;
for(Iterator iter = keys.iterator();iter.hasNext();){
/*这里的休眠作用:为了让大家看到,使用传统的private ArrayList keys = new ArrayList();
* 会导致Exception in thread "Thread-1" java.util.ConcurrentModificationException异常
* 因为迭代的过程中不能进行其他操作;你非要在迭代的时候向其中添加数据就会导致这种异常,而且在迭代中放入休眠这种错误百发百中。
*/
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
Object oo = iter.next();
if(o.equals(oo)){
o = oo;
}
}
}
//这里为了区别是不同对象,所以不能直接使用synchronized(key)
synchronized(o)
//大括号内的是需要同步的代码,不能改动
{
try{
Thread.sleep(1000);
System.out.println(key+":"+value+":" + (System.currentTimeMillis() / 1000));
}catch(Exception e){
e.printStackTrace();
}
}
}
}

其它面试题:

https://www.cnblogs.com/Jansens520/p/8624708.html

Java多线程常用面试题(含答案,精心总结整理)

JAVA多线程学习十七 - 面试题的更多相关文章

  1. Java多线程学习(转载)

    Java多线程学习(转载) 时间:2015-03-14 13:53:14      阅读:137413      评论:4      收藏:3      [点我收藏+] 转载 :http://blog ...

  2. “全栈2019”Java多线程第二十七章:Lock获取lock/释放unlock锁

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. “全栈2019”Java多线程第十七章:同步锁详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  4. Java多线程学习(六)Lock锁的使用

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  5. Java多线程学习(五)线程间通信知识点补充

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  6. Java多线程学习(四)等待/通知(wait/notify)机制

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  7. Java多线程学习(三)volatile关键字

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  8. Java多线程学习(二)synchronized关键字(2)

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  9. Java多线程学习(二)synchronized关键字(1)

    转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...

随机推荐

  1. WHT, SLANT, Haar

    目录 基本 酉变换 WALSH-HADAMARD TRANSFORMS sequency-ordered WHT SLANT TRANSFORM Haar Transform Gonzalez R. ...

  2. Chapter 12 IP Weighting and Marginal Structural Model

    目录 12.1 The causal question 12.2 Estimating IP weights via modeling 12.3 Stabilized IP weights 12.4 ...

  3. BUUCTF [极客大挑战 2019]Not Bad

    总的来说这是一个64位orw的题 开头先在主函数里分配了一个很大的空间 1 __int64 __fastcall main(int a1, char **a2, char **a3) 2 { 3 mm ...

  4. 使用 history 对象和 location 对象中的属性和方法制作一个简易的网页浏览工具

    查看本章节 查看作业目录 需求说明: 使用 history 对象和 location 对象中的属性和方法制作一个简易的网页浏览工具 实现思路: 使用history对象中的 forward() 方法和 ...

  5. Kinaba及X-Pack插件安装

    Kibana可视化管理平台安装,以及Kibana安装X-Pack插件: 基于已经安装好的6.2.2版本的Elasticsearch,安装6.2.2版本的Kibana. 基于已经安装好的6.2.2版本的 ...

  6. CSS基础 结构伪类选择器 last-child、first-child和nth-of-type的使用方法

    一.通过伪类选择器查找单个标签元素html结构 <div> <a herf='#'>导航1</a> <a herf='#'>导航2</a> ...

  7. 初识python: 装饰器

    定义: 本质是函数,功能是"装饰"其它函数,即为其他函数添加附加功能原则: 1.不能修改被装饰函数的源代码: 2.不能修改被装饰函数的调用方式实现装饰器知识储备: 1.函数即&qu ...

  8. [ bootstrap ] 图片内容占用padding的范围,如何解决?

    问题描述: 从效果图看到,图片内容占据了padding的范围,怎么解决呢? html代码 <div class="container"> <div class=& ...

  9. spring cloud Zuul 多层拦截 --- 心得

    1.前言 根据教材.博客文章的实例实操,基本都是单层拦截,没有找到多层拦截的具体写法 ,让我走了很多弯路,我将其写在这里,以待以后参考. 2.环境 spring boot : 2.1.6.RELEAS ...

  10. 【数据结构】图的基本操作——图的构造(邻接矩阵,邻接表),遍历(DFS,BFS)

    邻接矩阵实现如下: /* 主题:用邻接矩阵实现 DFS(递归) 与 BFS(非递归) 作者:Laugh 语言:C++ ***************************************** ...