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 ...
随机推荐
- JavaScript实现队列结构(Queue)
JavaScript实现队列结构(Queue) 一.队列简介 队列是是一种受限的线性表,特点为先进先出(FIFO:first in first out). 受限之处在于它只允许在表的前端(front) ...
- git删除远程仓库中的文件夹
具体操作如下: git rm -r --cached .history #删除目录 git commit -m”删除.history文件夹” git push -r表示递归所有子目录,如果你要删 ...
- ES6的Proxy
最近在Javascript的设计编程中,用到的那个单例模式,感觉就类似一种代理的思想[其实就是缓存的一种机制],单例模式就是: function getSingle(fn){ var result; ...
- vue安卓4.4.2页面打不开的坑
项目上线两三天,有保障说安卓下面页面打不开,所以查了下具体原因,系统版本过低,安卓4.4.2,然后发现本地没有babel-polyfill的包,具体解决方案如下: 1,npm 安装 npm insta ...
- ZipArchive(解压文件)
一.首先介绍minizip 的使用方法 ziparchive是基于开源代码”MiniZip”的zip压缩与解压的Objective-C 的Class,使用起来非常的简单方法:从http://code. ...
- AJAX轮询的实时监控画面
上一篇我们通过异步刷新Ajax 技术,来实现监控页面监控位号值的刷新,采用Ajax (Asynchronous Javascript And XML)技术,是指一种创建交互式.快速动态网页应用的网页开 ...
- WEB渗透 - HTTP协议基础
年初八 星灯花 https只能提高传输层安全 每一次客户端和服务端的通信都是独立的过程 cookie包括了sessionID和其他信息 重要的header S - C Set-Cookie:服务器发给 ...
- 软件基础1Word文档编辑
word文档编辑 启动Word2010 创建文档,<你好word>. 编辑文字. 保存的三种方式. ctrl+s. 点击文件选择保存,或另存为. 快速工具栏保存按钮. 设置字体 1.通过工 ...
- JVM04——七个GC垃圾收集器,一个都不能少
了解了JVM内存区域与垃圾回收算法,今天将为各位带来关于垃圾收集器的知识.关注我的公众号「Java面典」了解更多 Java 相关知识点. Java 堆内存被划分为新生代和老年代两部分,因此 JVM 通 ...
- Python中使用os模块执行远程命令
1. 使用os模块远程执行命令 服务端代码 1 import socket 2 import os 3 4 sh_server = socket.socket() #创建一个socket对象 5 sh ...