【Java多线程手写代码】(一):启动两个线程交替顺序打印奇偶数

阿里面试题:手写两个线程一个线程打印1,一个线程打印0,依次交替 阿里一面上来就让手写一个多线程模型,利用condition来实现1和0的交替执行,着实把我弄懵逼了,凭借着自己微弱的记忆,大致写出了如下: 基本思路是: 1、线程 操作 (方法) 资源类 2、判断 干活 通知 3、利用while判断来防止虚假唤醒机制 第一种方法利用Lock进行加锁解锁: public class ProducerAndConsumer { public static void main(String[] args) 阅读详情

我是少侠露飞。学习塑造人生,技术改变世界。

前言

Java多线程这块是企业面试的热门知识点,面试官也喜欢让候选人手写部分代码,主要为了考察候选人对线程同步机制的理解及使用熟练度。诸如启动两个线程交替打印1~100的奇偶数这种问题张口就来。

面试题分析

其实交替打印奇、偶数就是想启动两个线程实现以下效果:

奇线程:1
偶线程:2
……
奇线程:99
偶线程:100

简单分析一下,首先是两个线程,其次是交替顺序打印。这可以联系到线程之间的通信问题。这时可以想到大致的方向就是加锁,哪个线程拿到锁就打印,然后释放锁让另一个线程获取锁。两个线程轮流拿到锁,实现交替打印的效果。

Object的wait/notify方式

线程通信首先大家能想到的应该是Object类的wait()/notify()机制。

当有多个线程处理等待状态时,notify()是随机唤醒其中一个,如果想唤醒所有,则应该调用notifyAll()方法。

此时我们应该定义两个线程,一个打印奇数,一个打印偶数,两个线程持有同一把对象锁(可以通过构造方法注入),这样就能保证线程之间的同步了。这里有三点需要注意:

  • 共享变量number在两个线程中通过获取到锁之后才能进行操作,我们都知道++操作是非原子性的,但是本例中通过锁保证同一时刻只有一个线程可以操作,所以无需使用AtomicInteger这类的原子变量。
  • 对于奇线程,若当前数字是偶数时(偶线程相反),就调用wait()方法阻塞等待,如果是奇数,则执行打印,并接着自增,然后通过notify()唤醒另一个线程。
  • 若上一步唤醒了线程之后,其实现在奇、偶线程都是在争抢CPU执行权的,如果还是被奇线程抢到了锁,但是判断当前number是偶数,所以会调用wait()操作进入等待。
public class Main {
    private static volatile int number = 1;
    private static final int MAX = 100;

    public static void main(String[] args) {
        Object monitior = new Object();
        Thread oddThread = new Thread(new OddThread(monitior));
        oddThread.setName("奇线程");
        Thread evenThread = new Thread(new EvenThread(monitior));
        evenThread.setName("偶线程");
        oddThread.start();
        evenThread.start();
    }

    /**
     * 奇数线程
     */
    static class OddThread implements Runnable {
        private Object monitor;

        public OddThread(Object monitor) {
            this.monitor = monitor;
        }

        @Override
        public void run() {
            while (number < MAX) {
                synchronized (monitor) {
                    while (number % 2 == 0) {
                        try {
                            monitor.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(Thread.currentThread().getName() + "-->" + number);
                    number++;
                    monitor.notify();
                }
            }
        }
    }

    /**
     * 偶数线程
     */
    static class EvenThread implements Runnable {
        private Object monitor;

        public EvenThread(Object monitor) {
            this.monitor = monitor;
        }

        @Override
        public void run() {
            while (number <= MAX) {
                synchronized (monitor) {
                    while (number % 2 != 0) {
                        try {
                            monitor.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(Thread.currentThread().getName() + "-->" + number);
                    number++;
                    monitor.notify();
                }
            }
        }
    }

}

通过一个volatile类型的变量控制

该方式的思路是,线程在volatile变量上无限循环,直到volatile变量变为false。变为false后,线程开始真正地执行业务逻辑,打印数字,最后,需要挂起自己,并修改volatile变量,来唤醒其他线程。

public class Main {
    private static volatile int number = 1;
    private static final int MAX = 100;
    private static volatile boolean flag = true;

    public static void main(String[] args) {
        Thread oddThread = new Thread(new OddThread());
        oddThread.setName("奇线程");
        Thread evenThread = new Thread(new EvenThread());
        evenThread.setName("偶线程");
        oddThread.start();
        evenThread.start();
    }

    /**
     * 奇数线程
     */
    static class OddThread implements Runnable {
        @Override
        public void run() {
            while (number < MAX) {
                while (flag) {
                    System.out.println(Thread.currentThread().getName() + "-->" + number);
                    number++;
                    flag = false;
                }
            }
        }
    }

    /**
     * 偶数线程
     */
    static class EvenThread implements Runnable {
        @Override
        public void run() {
            while (number <= MAX) {
                while (!flag) {
                    System.out.println(Thread.currentThread().getName() + "-->" + number);
                    number++;
                    flag = true;
                }
            }
        }
    }

}

通过原子变量AtomicInteger和闭锁CountDownLatch实现

public class Main {
    private static ExecutorService executorService = new ThreadPoolExecutor(2, 5, 1000L,
            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024));

    private static CountDownLatch countDownLatch = new CountDownLatch(2);
    private static volatile boolean flag = false;
    private static AtomicInteger num = new AtomicInteger(1);
    private static final Integer MAX = 100;

    public static void main(String[] args) throws InterruptedException {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                while (num.get() <= MAX ) {
                    if (!flag) {
                        System.out.println(Thread.currentThread().getName() + "-->" + num.getAndIncrement());
                        flag = true;
                    }
                }
                countDownLatch.countDown();
            }
        });
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                while (num.get() <= MAX) {
                    if (flag) {
                        System.out.println(Thread.currentThread().getName() + "-->" + num.getAndIncrement());
                        flag = false;
                    }
                }
                countDownLatch.countDown();
            }
        });
        countDownLatch.await();
    }
}

我是少侠露飞,咱们下期见。

多线程顺序打印的5种解法 多线程同步的方式有许多,有传统的synchronized锁,还可以使用lock锁,下面列举多线程顺序打印的5种解法,算作对线程同步的一个总结。 文章目录经典面试题 经典面试题 1.三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC…”的字符串 2.两个线程交替打印 0~100 的奇偶数 3.通过 N 个线程顺序循环打印从 0 至 100 4.多线程按顺序调用,A->B->C,AA 打印 5 次,BB 打印10 次,CC 打印 15. 阅读详情

相关推荐

实现多线程交替打印问题

方法:在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。无论线程1、线程2、线程3哪个先执行,最后执行的顺序都是线程1——>线程2——>线程3。再看第三个问题,N个线程循环打印1-100,其实仔细想想这个和三个线程循环打印ABC并没有什么本质区别,只需要加上判断是否到了打印数字的最大值的语句即可。其实这类问题本质上都是线程通信问题,思路基本上都是一个线程执行完毕,阻塞该线程,唤醒其他线程,按顺序执行下一个线程。,只有线程B拿到锁后,不被阻塞,执行。

奋斗男孩的博客 1187

多线程并发场景题(持续更新)

多线程场景

lannister_awalys_pay的博客 495

Java多线程轮流打印奇数和偶数

类似于OddPrinter,EvenPrinter类的构造函数接受一个锁对象和要打印的最大偶数。当我们运行这段代码时,OddPrinter线程将打印从1到10之间的奇数,EvenPrinter线程将打印从2到10之间的偶数。在Main类的main方法中,我们创建了一个共享的锁对象和一个表示最大数字的变量。然后,我们创建了一个OddPrinter线程和一个EvenPrinter线程,并将它们启动。通过合理地使用锁对象和线程间的等待和通知机制,我们可以实现线程之间的协作,以达到预期的结果。

DevProZ的博客 371

多线程面试总结

(1)、synchronize和lock有什么区别?底层都是如何实现的?synchronize是不是可重入锁? (2)、threadLocal (3)、volatile (4)、线程池的原理,核心参数的含义,有哪些拒绝策略

xuehuagongzi000的博客 698

SAP固定资产原值与净值取值逻辑全解析:从数据表到ABAP实战

在企业资源计划(ERP)系统中,固定资产的价值管理是财务会计的核心模块,其关键在于准确核算资产原值与净值。从技术原理上看,这涉及对资产全生命周期业务(如购置、折旧、转移、报废)的财务建模,以及底层数据表(如ANLC、ANEP)的精准关联与计算。掌握这一逻辑的技术价值在于,能够确保财务报表数据的准确性,满足合规性要求,并为管理决策提供可靠依据。在SAP ECC或S/4HANA系统的应用场景中,ABAP开发者与财务顾问常需通过编写报表程序,从复杂的数据结构中提取资产价值信息。本文聚焦于SAP资产会计模块,深入剖

weixin_30984001的博客 393

从URDF到仿真动画:基于Simulink、Simscape与S-Function的机械臂一体化建模与控制

本文详细介绍了从URDF文件到高保真仿真动画的一体化机械臂建模与控制流程。通过整合Simulink、Simscape与S-Function,构建了包含物理特性的虚拟机械臂模型,并实现了自适应滑模等高级控制算法的嵌入与验证。该流程打通了从机械设计到控制算法验证的闭环,为机器人开发提供了高效的仿真平台。

cnn8visionary的博客 698

多种方法实现两个线程交替打印奇偶数

交替打印奇偶数 问题描述: 构造两个线程,交替打印1-100之间的数字,其中线程1打印奇数,线程2打印偶数。 方式1:采用synchronized同步锁和wait,notify线程通信机制来实现。 public class jiaotidayinshuzi { public static void main(String[] args){ PrintNum p...

bruce_xia6116的博客 3270

手把手教你用Docker快速部署开源MES系统(附避坑指南)

本文提供了一份详细的实战指南,手把手教你使用Docker容器化技术快速部署开源MES系统。内容涵盖从环境准备、项目选型、数据库配置到应用服务器优化、前端部署及生产环境监控的全流程,并附有避坑指南,旨在帮助中小制造企业IT人员和开发者低成本、高效率地构建智能制造解决方案。

f0g1h2的博客 1060

实现两个线程交替打印 0~100 的奇偶数

有两个线程,一个线程只打印奇数,一个线程只打印偶数,而且要按照顺序打印,就是说要按照这样的方式打印: 偶线程:0 奇线程:1 偶线程:2 奇线程:3 ...

技术分享,读书笔记,面试宝典,算法积累,应有尽有~ 1975

Anomalib实战指南:从零开始构建自定义异常检测数据集

本文提供了一份详细的Anomalib实战指南,指导用户从零开始构建自定义异常检测数据集。文章深入解析了数据准备的核心步骤、目录结构规范,并对比了PatchCore与FastFlow等关键模型的适用场景。通过清晰的代码示例,手把手演示了环境配置、模型训练与推理评估的全流程,旨在帮助开发者快速掌握这一工业视觉异常检测利器,有效解决实际生产中的缺陷识别难题。

weixin_29054245的博客 643

基于ROS下的安卓手机图像和IMU跑ORB-SLAM3

接之前文章继续,手上没有现成的单目+IMU硬件,但是安卓手机几乎人人都有。因此,本文讲下如何用手机跑ORB-SLAM3的Mono和Mono_Inertial。 1. 手机与PC通信 基于ROS下的信息发布和订阅,手机和PC在一个局域网下进行信息(image和IMU)传输。 手机APK参考了github上的2个开源Android_Camera-IMU和android_ros_sensors,基于ros_java生成安卓APP,下载安装任一个APP到安卓手机,界面分别是这样: 手机和PC连一个无

h_372101的博客 1万+

JAVA两个线程交替打印

JAVA两个线程交替打印题目使用java.util.concurrent.locks.ReentrantLock;注意点:流程图代码 题目 两个线程,一个负责打印1,3,5.。。。99; 另一个负责打印2,4,6,。。。100; 要交替进行,最后打印出来的次序是1,2,3,4,5,6,。。。99,100 使用java.util.concurrent.locks.ReentrantLock; 分析,...

gzjungle的博客 5051

BME688传感器原理图设计,已量产(环境传感器)

在便携式空气质量监测、可穿戴健康设备这类低功耗场景中,BME688 这类集成了 VOC、温湿度、气压的四合一 MEMS 传感器越来越受欢迎 —— 它体积小、功耗低,刚好匹配便携设备的需求。但这类小信号传感器对电源噪声、电平匹配的要求很细,今天结合实际项目里的一款 BME688 接口电路,聊聊硬件设计的关键细节。

不脱发的程序猿 515

笔试题: 使用两个线程交替打印奇偶数

项目路径: 创建一个打印数字的对象,对象内有一个用于计数的成员变量,一个用于打印偶数的方法,一个用于打印奇数的方法.通过使用阻塞的方式来决定当前线程是否可以打印. PrintNum.java package com.beikai.springboottestdemo.writtentest.Thread; /** * @ClassName PrintNum * @Description T...

kai3123919064的博客 1406

芒果YOLOv5改进05:损失函数IoU 篇之Repulsion Loss:原创改进损失函数 Repulsion:解决目标遮挡场景下检测,为解决密集人群检测中遮挡设计的损失函数,打造高效检测器涨点

YOLOv5改进代码实践|结合Repulsion 解决目标遮挡场景下检测🚀

包括YOLOv5、YOLOv7、YOLOv8等模型改进 4565

MobileViT替换YOLOv11主干网络:轻量化新思路-(用MobileViT等轻量视觉Transformer降低计算成本)

在计算机视觉领域,目标检测一直是核心任务之一,而YOLO(You Only Look Once)系列算法因其出色的速度-精度平衡成为工业界和学术界的热门选择。随着YOLOv11的推出,模型性能达到了新的高度,但其计算复杂度和参数量也随之增加,这对资源受限的移动设备和嵌入式系统提出了挑战。与此同时,视觉Transformer(ViT)的出现为计算机视觉带来了全新范式,但其庞大的计算需求限制了在移动端的应用。MobileViT作为一种创新的轻量级视觉Transformer架构,巧妙结合了CNN的归纳偏置优势和V

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 1647

(多线程)leetcode1116. 打印零与奇偶数

假设有这么一个类: class ZeroEvenOdd { public ZeroEvenOdd(int n) { ... } // 构造函数 public void zero(printNumber) { ... } // 仅打印出 0 public void even(printNumber) { ... } // 仅打印出 偶数 public void odd...

少说,多做。 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

多线程交替打印ABC以及两个线程交叉打印100以内奇偶数

一、两个线程交叉打印100以内奇偶数,打印结束后线程正常结束。 实现方式一: 实现方式二: 二、3个线程交替打印ABC 1.通过ReentrantLock我们可以很方便的进行显式的锁操作,即获取锁和释放锁,对于同一个对象锁而言,统一时刻只可能有一个线程拿到了这个锁,此时其他线程通过lock.lock()来获取对象锁时都会被阻塞,直到这个线程通过lock.unlock()操作释放...

ycllycll的博客 614

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

线程交替打印奇偶数(wait和notify实现以及原理简介)

wait和notify是Object的方法,不是thread的方法。 Object,notify()作用是唤醒持有这个Object对象锁的线程, Object,wait()作用是让当前线程进入阻塞状态。 因此 notify和wait只能用于synchronized内部,因为synchronized会指定对象锁, 而wait的前提是当前线程持有锁。 如果不在synchronized代码包含范围内会报...

hello world 4227

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

这道阿里巴巴多线程面试题,你学会了没有?

点关注,不迷路;持续更新Java相关技术及资讯!!! 背景 在前几天,群里有个群友问了我一道面试阿里的时候遇到的多线程题目,这个题目比较有意思,在这里和大家分享一下。 废话不多说,直接上题目: 通过N个线程顺序循环打印从0至100,如给定N=3则输出: thread0: 0 thread1: 1 thread2: 2 thread0: 3 thread1: 4 ..... 一些经常刷面试题...

XingXing_Java的博客 4835

java 多线程顺序执行

这道阿里巴巴多线程面试题,你学会了没有? 置顶2019年06月14日 15:43:55XingXing_Java阅读数 447 点关注,不迷路;持续更新Java相关技术及资讯!!! 前言 有个朋友问了我一道面试阿里的时候遇到的多线程题目,这个题目在这里和大家分享一下。 废话不多说,直接上题目: 通过N个线程顺序循环打印从0至100,如给定N=3则输出: threa...

jacke121的专栏 7315

线程(一):交替打印

交替打印的常见场景

WuLiang_995的博客 2453

java 并发 两个线程交替打印 奇数偶数

public class Service { private final Object lock = new Object(); private int odd = -1; private int even = -2; /* 线程启动先后顺序无法预料,最后启动的线程释放锁,执行notify */ private int first_start_od...

wang603603的专栏 1208

线程学习 两个线程交替打印奇偶数

/** * @author: 刘磊 * @Description: 交替打印奇偶数 * @date: 2019/3/26 14:07 **/ public class Test { static class NUM{ int i = 0; } static NUM num = new NUM(); @org.junit.Test p...

qq_36592394的博客 399

两个线程交替打印奇偶数

public class AlternatePrintingTest implements Runnable { int num = 1; static Object lock = new Object(); @Override public void run() { synchronized (lock) { while (true) { lock.notify(); ...

qq_34340853的博客 174

Java中利用多线程交替打印奇偶数

线程交替打印奇偶数涉及到的三个方法: 涉及到的三个方法: wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。 notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。 notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。 **** 说明:*** 1.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。 2.wait(),notify(),notifyAll()三个方

spade_Kwo的博客 785
上一篇: 【数据结构与算法】腾讯面试官让我模拟快排的执行过程,背好的代码竟无用武之地
下一篇: 【Java多线程手写代码】(二):利用多线程模拟动车票售卖
少侠露飞
博客等级 码龄9年 214粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值