热门面试题——多线程(源码案例详解)

简介: 热门面试题——多线程(源码案例详解)

问题一:写一个程序,证明AtomicInteger类比synchronized更高效

synchronized更高效
案例一

package duoxiancheng2;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author yeqv
 * @program A2
 * @Classname Ms4
 * @Date 2022/2/7 20:04
 * @Email w16638771062@163.com
 */
public class Ms4 {

    AtomicInteger n = new AtomicInteger(10000);
    int num = 10000;

    public static void main(String[] args) {

        var t = new Ms4();
        new Thread(t::minus, "T1").start();
        new Thread(t::minus, "T2").start();
        new Thread(t::minus, "T3").start();
        new Thread(t::minus, "T4").start();
        new Thread(t::minus, "T5").start();
        new Thread(t::minus, "T6").start();
        new Thread(t::minus, "T7").start();
        new Thread(t::minus, "T8").start();

    }

    void minus() {
        var a = System.currentTimeMillis();
        while (true) {
           /* if (n.get() > 0) {
                n.decrementAndGet();
                System.out.printf("%s 售出一张票,剩余%d张票。 %n", Thread.currentThread().getName(), n.get());
            } else {
                break;
            }*/
            synchronized (this) {
                if (num > 0) {
                    num--;
                    System.out.printf("%s 售出一张票,剩余%d张票。 %n", Thread.currentThread().getName(), num);
                } else {
                    break;
                }


            }


        }
        var b = System.currentTimeMillis();
        System.out.println(b - a);
    }
}

synchronized结果:
在这里插入图片描述
AtomicInteger结果:
在这里插入图片描述

问题二:写一个程序证明AtomXXX类的多个方法并不构成原子性

package demo16;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 写一个程序证明AtomXXX类的多个方法并不构成原子性
 */
public class T {
    AtomicInteger count = new AtomicInteger(0);

    void m() {
        for (int i = 0; i < 10000; i++) {
            if (count.get() < 100 && count.get() >= 0) { //如果未加锁,之间还会有其他线程插进来
                count.incrementAndGet();
            }
        }
    }

    public static void main(String[] args) {
        T t = new T();
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            threads.add(new Thread(t::m, "thread" + i));
        }
        threads.forEach(Thread::start);
        threads.forEach((o) -> {
            try {
                //join()方法阻塞调用此方法的线程,直到线程t完成,此线程再继续。通常用于在main()主线程内,等待其它线程完成再结束main()主线程。
                o.join(); //相当于在main线程中同步o线程,o执行完了,main线程才有执行的机会
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(t.count);
    }
}

**

问题三:写一个程序,在main线程中启动100个线程,100个线程完成后,主线程打印“完成”

package cn.thread;

import java.util.concurrent.CountDownLatch;

/**
 * 写一个程序,在main线程中启动100个线程,100个线程完成后,主线程打印“完成”
 *
 * @author webrx [webrx@126.com]
 * @version 1.0
 * @since 16
 */
public class T12 {
    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(100);
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                String tn = Thread.currentThread().getName();
                System.out.printf("%s : 开始执行...%n", tn);
                System.out.printf("%s : 执行完成,程序结束。%n", tn);
                latch.countDown();
            }, "T" + i).start();
        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("---------------------------------------");
        System.out.println("100个线程执行完了。");
        String tn = Thread.currentThread().getName();
        System.out.printf("%s : 执行完成,程序结束。%n", tn);
    }
}
相关文章
|
3天前
|
消息中间件 前端开发 Java
美团面试:如何实现线程任务编排?
线程任务编排指的是对多个线程任务按照一定的逻辑顺序或条件进行组织和安排,以实现协同工作、顺序执行或并行执行的一种机制。 ## 1.线程任务编排 VS 线程通讯 有同学可能会想:那线程的任务编排是不是问的就是线程间通讯啊? 线程间通讯我知道了,它的实现方式总共有以下几种方式: 1. Object 类下的 wait()、notify() 和 notifyAll() 方法; 2. Condition 类下的 await()、signal() 和 signalAll() 方法; 3. LockSupport 类下的 park() 和 unpark() 方法。 但是,**线程通讯和线程的任务编排是
|
5天前
|
NoSQL 安全 Unix
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅(中)
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅
16 0
|
1天前
|
Oracle Java 关系型数据库
一次惨痛的面试:“网易提前批,我被虚拟线程问倒了”
一次惨痛的面试:“网易提前批,我被虚拟线程问倒了”
25 4
|
2天前
|
JavaScript 中间件 前端开发
[评论送书 ]手撕源码,实现一个Koa。,2024年最新学生会面试答题技巧
[评论送书 ]手撕源码,实现一个Koa。,2024年最新学生会面试答题技巧
|
2天前
|
数据安全/隐私保护 Python 算法
Python 蜻蜓fm有声书批量下载 支持账号登录 原创源码,2024年最新Python面试回忆录
Python 蜻蜓fm有声书批量下载 支持账号登录 原创源码,2024年最新Python面试回忆录
|
2天前
|
前端开发 JavaScript 程序员
async-validator 源码学习(一):文档翻译,2024年最新如何面试大厂
async-validator 源码学习(一):文档翻译,2024年最新如何面试大厂
|
2天前
|
移动开发 前端开发 JavaScript
10款精美的web前端源码的特效,2024年最新面试题+笔记+项目实战
10款精美的web前端源码的特效,2024年最新面试题+笔记+项目实战
|
2天前
|
移动开发 前端开发 JavaScript
10款精美的web前端源码的特效(1),头条前端面试节奏
10款精美的web前端源码的特效(1),头条前端面试节奏
|
2天前
|
Python
【python学习小案例】提升兴趣之模拟系统入侵,2024年最新面试阿里运营一般问什么
【python学习小案例】提升兴趣之模拟系统入侵,2024年最新面试阿里运营一般问什么
|
3天前
|
NoSQL 算法 Java
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
【redis源码学习】持久化机制,java程序员面试算法宝典pdf