Java并发编程(三):CountDownLatch(闭锁)原理及利用闭锁实现两个线程分别输出100以内的奇数和偶数

【面试题】创建两个线程交替打印100以内数字(一个打印偶数一个打印奇数) 基本策略是使用锁来控制线程的执行顺序。拿到锁的线程可以执行打印操作,然后释放锁,让另一个线程有机会获取锁。这样,两个线程就可以轮流获得锁,实现交替打印的效果。 阅读详情

1 引言

在实际开发中,经常遇到这样一种场景:有一组线程,每个线程去持行自己的任务,现在想实现等所有线程都持行完毕后,再向下执行代码。比如我们开启一组线程去同步服务器的数据,点赞记录,下载记录,收藏记录等等用户信息,所有数据同步完成之后继续向下执行。

2 CountDownLatch的概念

CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,用于开启一组线程,使一个线程在等待这组线程完成各自工作之后,再继续执行。CountDownLatch内部基于一个计数器实现。计数器初始值大于等于线程的数量(因为每个线程至少执行countDown()方法一次)。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成指定的任务,然后在CountDownLatch上等待的线程就可以继续执行接下来的任务。

3 CountDownLatch的方法

CountDownLatch的主要方法包括:

//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };   
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  
//将count值减1
public void countDown() { };  

4 CountDownLatch的示例

假设现在有这样的场景:两个阅卷老师同时对两个班级的学生进行评分,最后需要统计出两个班级所有学生的最高分和最低分。这里可以利用CountDownLatch的思想,启动两个线程分别对两个班级分数进行排序,在两个班级都排好序之后,再综合比较得出最大值和最小值。(当然这种场景启动两个线程消耗更大,效率较低。实际上可以通过插入排序、快速排序实现,本例方案的合理性不做讨论,只是为了演示CountDownLatch的用法)。

附实现代码:

/**
 * @author Carson Chu, 1965704869@qq.com
 * @date 2020/4/5 12:41
 * @description
 */
public class Main {
    public static void main(String[] args) {
        int[] score0 = {2, 6, 7, 9, 3};
        int[] score1 = {8, 6, 7, 1, 5};
        /* 初始化CountDownLatch,包含两个计数器 */
        CountDownLatch countDownLatch = new CountDownLatch(2);
        ExecutorService executorService0 = Executors.newCachedThreadPool();
        /* 线程1对第一个数组进行排序 */
        executorService0.submit(() -> {
            Arrays.sort(score0);
            /* 执行完计数器减1 */
            countDownLatch.countDown();
        });

        ExecutorService executorService1 = Executors.newCachedThreadPool();
        /* 线程2对第二个数组进行排序 */
        executorService1.submit(() -> {
            Arrays.sort(score1);
            /* 执行完计数器减1 */
            countDownLatch.countDown();
        });
        try {
            /* 阻塞当前线程--main线程 */
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int maxRes = score0[4] > score1[4] ? score0[4] : score1[4];
        int minRes = score0[0] < score1[0] ? score0[0] : score1[0];
        System.out.println("The maximum score is " + maxRes);
        System.out.println("The minimum score is " + minRes);
    }
}

5 CountDownLatch源码分析

CountDownLatch底层是基于AbstractQueuedSynchronizer(即大名鼎鼎的AQS)实现的,AQS主要有两种模式:共享模式(SHARED)和互斥模式(EXCLUSIVE),CountDownLatch是基于共享模式的,内部封装了一个继承自AQS的类Sync,附源码:

程序清单5-1 Sync源码

private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int count) {
            setState(count);
        }

        int getCount() {
            return getState();
        }

        /* 调用await()方法的底层实现 */
        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }

        /* 调用countDown()方法的底层实现 */
        protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }

每次调用await()方法时候,会利用上述代码里的tryAcquireShared()获取当前计数器数量,如果不为0,则执行如下代码,这段代码是干嘛的呢,就是把所有等待的线程放入一个CLH队列中。
程序清单5-2 await()方法核心实现

/**
     * Acquires in shared interruptible mode.
     * @param arg the acquire argument
     */
    private void doAcquireSharedInterruptibly(int arg)
        throws InterruptedException {
        final Node node = addWaiter(Node.SHARED);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head) {
                    int r = tryAcquireShared(arg);
                    if (r >= 0) {
                        setHeadAndPropagate(node, r);
                        p.next = null; // help GC
                        failed = false;
                        return;
                    }
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

每次调用countDown()方法时候,会利用程序清单5-1代码里的tryReleaseShared()来判断当前计数器是否为0,如果为0则直接返回,如果不为0,则计数器减1,当计数器被减到0的时候,返回true,继续执行如下代码以唤醒线程(唤醒操作是基于LockSupport.unpark()实现的)。
关于LockSupport的机制及原理可参考我的另一篇博客,附传送门↓:
Java并发编程(二):LockSupport应用及原理分析

程序清单5-3 countDown()方法核心实现

private void doReleaseShared() {
    
        for (;;) {
            Node h = head;
            if (h != null && h != tail) {
                int ws = h.waitStatus;
                if (ws == Node.SIGNAL) {
                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
                        continue;            // loop to recheck cases
                    //唤醒h线程
                    unparkSuccessor(h);
                }
                else if (ws == 0 &&
                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                    continue;                // loop on failed CAS
            }
            if (h == head)                   // loop if head changed
                break;
        }
    }

6 利用CountDownLatch实现两个线程分别输出100以内的奇数和偶数

/**
 * @author Carson
 * @date 2020/7/4 13:03
 */
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 = true;
    private static AtomicInteger num = new AtomicInteger();
    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 - 1) {
                    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();
    }
}

7 小结

要实现线程同步,除了CountDownLatch外,Java还提供了了一种内存屏障的机制CyclicBarrier,两者的区别在于:

  • CountDownLatch是一个计数器,线程完成一个记录一个,计数器递减,只能用一次
  • CyclicBarrier的计数器更像一个阀门,需要所有线程都到达,然后继续执行,计数器递增,提供reset功能,支持重置多次使用。

点点关注,不会迷路

java 输出100之间的所有奇数 java 输出100之间的所有奇数 java 输出100之间的所有奇数 立即下载

相关推荐

Java线程使用同步锁交替执行打印奇数偶数的方法

主要介绍了Java线程使用同步锁交替执行打印奇数偶数的方法。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

CountDownLatch概念

CountDownLatch概念 CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。 CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。 CountDownLatch的用法

qq_40981804的博客 453

[Multisim][模电实验]简易函数信号发生器的设计与实现_北京邮电大学2019级信通院电子电路实验下

本文记述了笔者设计并实现以±12V供电电压输出1KHZ~10KHZ频率连续可调的方波、三角波和正弦波的过程。其中,方波输出电压峰峰值为12V(误差<20%),占空比可调、三角波输出电压峰峰值为8V(±20%),正弦波输出电压峰峰值≥1V。

lgc0208的博客 4万+

使用多线程实现两个子线程分别对1~100的奇偶输出

方法一:创建两个对象实现package com.atguigu.thread.exer; class SubThread1 extends Thread{ public void run(){ for (int i = 1; i &lt;= 100; i++) { if (i%2==0) { System.out.println(currentThread().getName...

mumihahaha的博客 851

Ubuntu16.04下禁用scp、sftp和winscp

在上一篇博文《Ubuntu16.04 搭建FTP服务器,设置用户权限为只许上传、禁止下载和删除》中,我讲述了Ubuntu16.04下配置FTP,并且设定用户权限为只能上传数据,禁止下载和删除数据。这算在FTP层面封堵了服务器数据泄露的途径。 但是,Ubuntu系统的scp和sftp还是起作用的,理论上只要能用本地机器ping通服务器,就可以用scp和sftp下载数据,这还是存在数据泄露可能的,所...

HPC&Geophysics攻城狮 5737

告别数据丢失焦虑:用Python手把手实现Reed-Solomon码(附完整代码)

本文详细介绍了如何使用Python实现Reed-Solomon纠错码(RS码),帮助开发者有效防止数据丢失。通过基础编解码实战、文件保护方案和高级性能优化技巧,读者可以轻松掌握这一前向纠错技术,应用于物联网、文件存储和网络传输等场景,提升数据可靠性。

weixin_42527160的博客 223

Java----实现多线程数组求和.

import java.util.Arrays; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class test { public static void main(String[] args) throws Execution

m0_56642224的博客 1709

VAY 是 SAP 自动科目确定(OBYC-GBB)中的科目修改码,专用于带科目分配对象的销售订单发货场景,核心是触发 “Dr 成本要素科目(如销售费用 / 特定成本对象) Cr 库存商品” 的分录,

摘要:VAY是SAP中用于带科目分配对象(如成本中心、WBS)的销售订单发货的科目修改码,与标准VAX场景不同,它生成"借成本要素科目/贷库存商品"的分录。配置路径为OBYC-GBB-VAY,需确保借方科目为成本要素。典型业务场景包括免费样品、项目专用发货等。常见问题包括VAY未触发或科目记账错误,需检查销售订单科目分配、移动类型设置及OBYC配置。特殊场景建议单独配置科目以便费用分析。

金牌架构师 1253

两个线程,顺序打印从1-100的数字,一个线程打印奇数,一个线程打印偶数

需求描述 这里考察对线程锁的使用,多线程情况下如何控制各自的执行时间段。 解题思路 我想到的有两种接替思路,一种是使用标志位,一种是使用线程锁。 使用标志位的思路如下: 两个线程一个打印偶数,一个打印奇数,两个线程要交叉执行,所以可以用一个长度为101的数组(第一个位置不用,便于打印的数字和位置保持一致)保存每个线程的执行状态,一个线程执行完毕后在对应位置设置成1,之前前判断数组中前一个位置是否为...

随便写写 5418

【2026最新版】Open3D(C++)点云处理算法汇总(C++长期更新版)

C++版本Open3D进行点云处理的一些算法使用案例。博客长期更新,最近一次更新时间为:2026年4月11日。

点云侠的博客 1万+

【Python爬虫教程】第3篇-解决使用reqeusts遇到的ProxyError异常

Python request代理错误提示“HTTPSConnectionPool, Cannot connect to proxy, no such file or directory”

分享技术,记录思考和感悟 1508

多线程按序打印之使用CountDownLatch遇到的问题及解决

多线程按序打印之使用CountDownLatch遇到的问题及解决 多线程的交替打印问题(如两个线程循环打印1到100、三个线程循环打印a到z等都可以使用CountDownLatch解决),这里记录我使用CountDownLatch遇到的一个bug。 先看使用两个线程交替打印1-100 public class PrintaToz { static int i = 0; public static void main(String[] args) { test(); }

qq_42363956的博客 1007

音频链路分析

音频链路分析摘要 本文分析了蓝牙音频设备(BES2700)的音频传输链路,主要包括通话和音乐播放两种场景: 通话链路: 下行:蓝牙接收数据→解码→通过Codec输出到扬声器 上行:麦克风采集→Codec处理→蓝牙编码发送 音乐播放链路: 通过A2DP协议接收高质量音频数据 经过解码、EQ调节等音频处理后输出 系统采用多线程消息机制处理音频任务,通过mailbox传递控制消息,由回调函数处理具体音频数据流。不同应用场景使用不同的蓝牙协议栈(HFP/HSP用于通话,A2DP用于媒体)和编码方式(mSBC/SBC

云淡风轻 85

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

两个线程交替打印奇偶数的问题

少侠露飞的学习笔记 1755

基于STM32的太阳能充电宝设计_资料编号31

系统硬件包括主控 STM32F103C8T6、0.96 OLED 显示屏、蜂鸣器、电源自锁开关、温度传感器 DS18B20、继电器、5 V DC 升压模块 、TB4056、18650锂电池、9 V太阳能板、稳压降压 5 V三极管。电源供应:锂电池为系统供电,9 伏太阳能板经 5 伏降压稳压三极管降压为 5 伏后传送到 TP4056,TP4056 为锂电池供电,因锂电池电压 3.7 伏,通过 5 伏 DC 升压模块升压到 5 伏为整个系统提供 5 伏电压。

嵌入式阿齐Archie 1万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Java多线程代码实战 2021.11.03

1.三种方式实现两个线程交替打印1、2. package com.ddd.common.work.thirdweek; import jdk.nashorn.internal.codegen.CompilerConstants; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * @program: DddJavaStudy * @description: 测试多线程的..

xinkuaile的专栏 494

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

并发编程---多线程经典面试题之交替打印奇数偶数

多线程基本功题目代码 题目 启动两个线程, 一个输出 1,3,5,7…99, 另一个输出 2,4,6,8…100 最后 STDOUT 中按序输出 1,2,3,4,5…100。 要求用 Java 的 wait + notify 机制来实现 提示:wait和notify必须配合synchronized使用 代码 public class PrintNum{ //可以是任意一个对象,或者自定义的对象 static Object o1 = new Object(); public st

烟花易冷 451

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

深度学习工具包 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")

使用两个线程分别输出100以内的奇数和偶数,并按从小到大的顺序输出

不啰嗦,直接上干货! 我用的是线程通讯wait(等待)和notify(唤醒)步骤如下: 首先定义一个公共类: package demo10; public class ShareData { public int i; public int max; public boolean isEven=false; public ShareData(int i,int m...

我是“哈哈” 4846

什么是闭锁?(ContDownLatch)

在完成某些运算时,只有其他所有线程的运算全部完成,当前运算才继续执行,这就叫闭锁。 java.util.concurrent包中提供了多种并发容器类来改进同步容器的性能。ContDownLatch是一个同步辅助类 **我们的需求是输出0-5000内的所有偶数,然后输出“耗费时间为x秒”。**看下面代码: public class TestCountDownLatch { public static void main(String[] args){ LatchDemo ld = ne

blindore的博客 1325

两个线程分别打印奇数偶数输出1-100

package com.study.thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class ThreadDemo { /** * 方法一 */ private static Reent...

BruceChao5211的博客 3669

Java如何模拟一百个线程同时执行(CountDownLatch,CyclicBarrier)

Java如何模拟一百个线程同时执行 对并发测试,在平常开发过程中并不容易在现。但是借助CountDownLatch和CyclicBarrier 可可以让线程同时等待同一个状态,在多核多线程的pc还是能大概的模拟出来,但是其实从真正意义上来说,并不是完全同时执行,cpu的资源是通过时间片轮转法进行调度。 上代码 CountDownLatch模拟多线程 @Test void testCountDownLatch(){ //等待100个线程同时执行 CountDo

qq_42271561的博客 4077

java-两种方式实现两个线程交替打印1-100(即交替打印100以内的奇数偶数)

java-两种方式实现两个线程交替打印1-100,经典java面试题,一定要手敲一遍。

weixin_73706387的博客 935

两个线程交替打印1-100奇偶数

第一种方式: public class Print奇偶数{ private static class Counter { public int value = 1; public boolean odd = true; } private static Counter counter = new Counter(); privat...

akuan1992的博客 531

java线程输出一百以内的偶数_Java两个线程轮换打印1-100内的奇数和偶数

目标:Java两个线程轮换打印1-100内的奇数和偶数问题:两个线程,一个打印1-100的奇数,一个打印1-100的偶数;要求:线程1打印5个之后,线程2开始打印,线程2打印5个之后,线程1再开始打印,以此循环。public class Test {//state==1表示线程1开始打印,state==2表示线程2开始打印private static int state = 1;private s...

weixin_28715081的博客 692

java go多线程:两个线程交替打印 0~100 的奇偶数

最近在实现raft算法,用到了很多go的高并发的知识,看到一道题写两个线程交替打印 1~100 的奇偶数,突然来了兴趣。 题目要求我们要启动两个线程,一个打印奇数,一个打印偶数。中途不能跳出协程。 算法思想:启动两个协程对同一个变量进行操作,当一个协程对该变量进行操作时进行加锁,另一个协程等待。释放锁后再进行操作,每次操作进行加1即可。 代码如下: import ( "fmt" "sync" "time" ) type Tongbu struct { count int mu sync.Mute

weixin_39802680的博客 1283
上一篇: Java并发编程(二):LockSupport应用及原理分析
下一篇: 你想要的String面试的知识点,这里都有
少侠露飞
博客等级 码龄9年 214粉丝 117原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值