一道很经典的多线程面试题

 XML Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.lyzx.restdy.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


/**
 * 关于多线程的一道面试题
 * 对于一个大数组求和(为模拟真实的情况没加一次等待20ms),
 * 要求使用多线程实现
 * 大致思路是把一个大数组分开,每个线程值计算其中一部分的和
 * 最后把结果合并
 */
public class T {
    
    public static void main(String[] args) {
        //数组长度
        int itemCount =2000;
        int[] arr = new int[itemCount];
        for(int i=0;i<itemCount;i++){
            arr[i]=i;
        }
        
        //线程数,使用线程池管理线程
        int threadCount = 10;
        ExecutorService es = Executors.newFixedThreadPool(threadCount);
        
        //使用计数器阻塞主线程,等待所有的数组求和完毕后放开主线程
        CountDownLatch latch = new CountDownLatch(threadCount);
        
        //分配每个线程计算一部分数组最后求和
        int perItem=itemCount/threadCount;
        Future<String>[] allFuture = new Future[perItem];
        
        for(int i=0;i<threadCount;i++){
            Future<String> f = es.submit(new Z(arr,i*perItem,perItem*(i+1),latch));
            allFuture[i]=f;
        }
        es.shutdown();
        int finalCount = 0;
        
        for(int i=0;i<threadCount;i++){
            try {
                String value = allFuture[i].get();
                finalCount += Integer.parseInt(value);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        
        //阻塞主线程等待计算数组和的线程执行完毕
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(finalCount);
    }
}



class Z implements Callable<String>{
    //[start,end)
    private int start =-1;
    private int end =-1;
    private int[] arr;
    private int count = 0;
    private CountDownLatch latch ;
    
    
    public Z(int[] arr,int start,int end,CountDownLatch latch){
        if(arr == null || start <0 || end <=0 || start > end || latch == null){
            throw new RuntimeException("param is Error");
        }
        this.arr = arr;
        this.start=start;
        this.end=end;
        this.latch = latch;
    }
    
    /**
     * 对于arr数组的start到end项累加
     */
    @Override
    public String call() throws Exception {
        for(int i=start;i<end;i++){
            //每相加一次就等待20毫秒,没有实际意义,只为了模拟实际的生成环境,可能出现的阻塞情况
            Thread.sleep(20);
            count += i;
        }
        latch.countDown();
        return String.valueOf(count);
    }
    
}
引用\[1\]:这是一个相对艰难的多线程面试问题,它能达到很多的目的。第一,它可以检测侯选者是否能实际的用Java线程写程序;第二,可以检测侯选者对并发场景的理解,并且你可以根据这个问很多问题。如果他用wait()和notify()方法来实现阻塞队列,你可以要求他用最新的Java 5中的并发类来再写一次。\[1\] 引用\[2\]:这是一道出现在多线程面试的高级阶段的问题。大多数的面试官会问最近你遇到的竞争条件,以及你是怎么解决的。有些时间他们会写简单的代码,然后让你检测出代码的竞争条件。可以参考我之前发布的关于Java竞争条件的文章。在我看来这是最好的java线程面试问题之一,它可以确切的检测候选者解决竞争条件的经验,orwriting code which is free of data race or any otherrace condition。关于这方面最好的书是《Concurrency practices in Java》。\[2\] 引用\[3\]:这是另一个非常经典的java多线程面试问题。这也是我刚开始写线程程序时候的困惑。现在这个问题通常在电话面试或者是在初中级Java面试的第一轮被问到。这个问题的回答应该是这样的,当你调用start()方法时你将创建新的线程,并且执行在run()方法里的代码。但是如果你直接调用run()方法,它不会创建新的线程也不会执行调用线程的代码。阅读我之前写的《start与run方法的区别》这篇文章来获得更多信息。\[3\] 问题: 2023java 多线程面试题 回答: 2023年的Java多线程面试题可能会涉及到多个方面的问题。其中一个可能是要求候选者用Java线程编写程序,以检测他们的实际操作能力和对并发场景的理解。另一个可能是关于竞争条件的问题,面试官可能会询问候选者最近遇到的竞争条件以及他们是如何解决的。还有一个经典的问题是关于start()方法和run()方法的区别,候选者需要知道调用start()方法会创建一个新的线程并执行run()方法中的代码,而直接调用run()方法则不会创建新的线程。对于这些问题,候选者可以参考相关的书籍和文章来加深理解和准备面试。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* *3* [15个顶级Java多线程面试题及答案](https://blog.youkuaiyun.com/2301_78102191/article/details/131085355)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值