leetcode并发题解
按序打印

解法一:使用volatile
public class FooWithVolatile {
private volatile int count;
public FooWithVolatile() {
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
count++;
}
public void second(Runnable printSecond) throws InterruptedException {
// printSecond.run() outputs "second". Do not change or remove this line.
while(count != 1) { }
printSecond.run();
count++;
}
public void third(Runnable printThird) throws InterruptedException {
while(count != 2) { }
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}
类似的,我们也可以使用AtomicInteger,不过其实AtomicInteger底层也是使用了volatile字段,只不过在计算时会使用CAS解决原子性问题,但是这里的while循环对自增操作进行了阻塞,所以不会出现三个线程同时对count自增的情况,所以没必要使用AtomicInteger,更何况CAS操作里面的while循环也是很耗费资源的
解法二:使用CountDownLatch
public class FooWithCountDownLatch {
private CountDownLatch second = new CountDownLatch(1);
private CountDownLatch third = new CountDownLatch(1);
public FooWithCountDownLatch() {
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
second.countDown();
}
public void second(Runnable printSecond) throws InterruptedException {
second.await();
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
third.countDown();
}
public void third(Runnable printThird) throws InterruptedException {
third.await();
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}
类似的,这里我们使用两个“门栓”栓住(阻塞)second方法和third方法执行run方法打印结果,当first方法执行完毕后,释放second的门栓让second方法打印结果,second方法执行完毕后,释放third的门栓让third方法打印结果
交替打印FooBar

class FooBarWithCountDownLatch {
private int n;
private CountDownLatch fooLatch = new CountDownLatch(0);
private CountDownLatch barLatch = new CountDownLatch(1);
public FooBarWithCountDownLatch(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
fooLatch.await();
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
fooLatch = new CountDownLatch(1);
barLatch.countDown();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
barLatch.await();
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
barLatch = new CountDownLatch(1);
fooLatch.countDown();
}
}
}
这里要注意,CountDownLatch和CyclicBarrier不一样,CountDownLatch是一次性的,countDown到0之后不会自己恢复成1,所以要每次new一个CountDownLatch对象。
打印零与奇偶数

public class ZeroEvenOdd {
private int n;
private CountDownLatch zero = new CountDownLatch(0);
private CountDownLatch even = new CountDownLatch(1);
private CountDownLatch odd = new CountDownLatch(1);
public ZeroEvenOdd(int n) {
this.n = n;
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
for (int i = 0; i < n; i++) {
zero.await();
printNumber.accept(0);
zero = new CountDownLatch(1);
if(i % 2 == 0) {
odd.countDown();
} else {
even.countDown();
}
}
}
public void even(IntConsumer printNumber) throws InterruptedException {
for (int i = 2; i < n; i+=2) {
even.await();
printNumber.accept(i);
even = new CountDownLatch(1);
zero.countDown();
}
}
public void odd(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i < n; i+=2) {
odd.await();
printNumber.accept(i);
odd = new CountDownLatch(1);
zero.countDown();
}
}
}
这道题没什么好说的,做法也同样很多样,只要仔细点,都可以做对,但是我感觉都没直接用CoutDownLatch好。
H2O

public class H2O {
private Semaphore hSemaphore = new Semaphore(2);
private Semaphore oSemaphore = new Semaphore(0);
public H2O() {
}
public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
hSemaphore.acquire();
// releaseHydrogen.run() outputs "H". Do not change or remove this line.
releaseHydrogen.run();
oSemaphore.release();
}
public void oxygen(Runnable releaseOxygen) throws InterruptedException {
oSemaphore.acquire(2);
// releaseOxygen.run() outputs "H". Do not change or remove this line.
releaseOxygen.run();
hSemaphore.release(2);
}
}
实在想不到Semaphore以外的做法,虽然看题解确实有,但是反而不怎么好
leetcode并发题解的更多相关文章
- LeetCode OJ 题解
博客搬至blog.csgrandeur.com,cnblogs不再更新. 新的题解会更新在新博客:http://blog.csgrandeur.com/2014/01/15/LeetCode-OJ-S ...
- Leetcode 简略题解 - 共567题
Leetcode 简略题解 - 共567题 写在开头:我作为一个老实人,一向非常反感骗赞.收智商税两种行为.前几天看到不止两三位用户说自己辛苦写了干货,结果收藏数是点赞数的三倍有余,感觉自己的 ...
- LeetCode 算法题解 js 版 (001 Two Sum)
LeetCode 算法题解 js 版 (001 Two Sum) 两数之和 https://leetcode.com/problems/two-sum/submissions/ https://lee ...
- leetcode & lintcode 题解
刷题备忘录,for bug-free 招行面试题--求无序数组最长连续序列的长度,这里连续指的是值连续--间隔为1,并不是数值的位置连续 问题: 给出一个未排序的整数数组,找出最长的连续元素序列的长度 ...
- LeetCode一句话题解
深度优先搜索 人生经验 1. 需要输出所有解.并由于元素集有重复元素,要求返回的结果需要去重的情况,可考虑使用值对应数量的map,然后分别考虑依次取不同数量该值的可能. LeetCode39 题目:给 ...
- [leetcode] 位操作题解
子集 题目[78]:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 示例: 输入: nums = [1,2,3] 输出: [ [3], [1], [2], [ ...
- LeetCode 中等题解(3)
34 在排序数组中查找元素的第一个和最后一个位置 Question 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂 ...
- LeetCode 中等题解(1)
16 最接近的三数之和 Question 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和. ...
- leetcode个人题解——two sum
这是leetcode第一题,通过较为简单. 第一题用来测试的,用的c,直接暴力法过, /** * Note: The returned array must be malloced, assume c ...
随机推荐
- 前端小姐姐学PHP之(二)
上次了我们配置好开发环境了,本小节主要讲述内容点: phpStrom的运行环境配置 创建数据库.数据表 连接数据库 一.phpStrom的运行环境配置(windows版) 注:MAC版原文地址 htt ...
- 【Java面试题】关于String,最近被问到了这2道面试题
1. 前言 最近面试了几家公司,体验了一下电话面试和今年刚火起来的视频面试, 虽然之前就有一些公司会先通过电话面试的形式先评估下候选人的能力水平,但好像不多,至少我以前的面试形式100%都是现场面试. ...
- Lambda 语法
1.java8 Lambda表达式语法简介 (此处需要使用jdk1.8或其以上版本) Lambd表达式分为左右两侧 * 左侧:Lambda 表达式的参数列表 * 右侧:Lambda 表达式中所需要执行 ...
- Json转化的三种方式
1. Gson 1.添加依赖 <dependency> <groupId>com.google.code.gson</groupId> <artifactId ...
- CJSON的封装API
为了更方便使用C的JSON库,对其进行了一层封装. H文件: #ifndef __JSONHELPER__ #define __JSONHELPER__ #ifdef __cplusplus exte ...
- CyclicBarrier源码探究 (JDK 1.8)
CyclicBarrier也叫回环栅栏,能够实现让一组线程运行到栅栏处并阻塞,等到所有线程都到达栅栏时再一起执行的功能."回环"意味着CyclicBarrier可以多次重复使用,相 ...
- arm 添加 ftp server 之 bftpd
本来想装vsftp 结果装上以后执行报错 Segmentation fault , 换到几个 其它的小型ftp server 软件 ,试了 Stupid-FTPd,不能用. bftpd 可以使用,Ti ...
- 前端要了解的seo
一.搜索引擎工作原理 当我们在输入框中输入关键词,点击搜索或查询时,然后得到结果.深究其背后的故事,搜索引擎做了很多事情. 在搜索引擎网站,比如百度,在其后台有一个非常庞大的数据库,里面存储了海量的关 ...
- 从源码看 PHP 7 数组的实现
本文所用源码为 PHP 7.4.4 的版本. PHP 7 数组概述 PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.此类型在很多方面做了优化,因此可以把它当 ...
- webstorm 开新项目 setting 设置@目录别名 add @ (languages & Framewors - Javascript - Webpack 4. setting eslint enable
webstorm 开新项目 setting 设置@目录别名 add @ (languages & Framewors - Javascript - Webpack 4. setting esl ...