Skip to content

Commit 67d08bb

Browse files
committed
New theme:Concurrency. update
1 parent 75349e0 commit 67d08bb

File tree

8 files changed

+474
-0
lines changed

8 files changed

+474
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
## 1114.按顺序打印
2+
3+
### 问题描述
4+
5+
我们提供了一个类:
6+
7+
```
8+
public class Foo {
9+
public void one() { print("one"); }
10+
public void two() { print("two"); }
11+
public void three() { print("three"); }
12+
}
13+
```
14+
15+
三个不同的线程将会共用一个 `Foo` 实例。
16+
17+
- 线程 A 将会调用 `one()` 方法
18+
- 线程 B 将会调用 `two()` 方法
19+
- 线程 C 将会调用 `three()` 方法
20+
21+
请设计修改程序,以确保 `two()` 方法在 `one()` 方法之后被执行,`three()` 方法在 `two()` 方法之后被执行。
22+
23+
24+
25+
**示例 1:**
26+
27+
```
28+
输入: [1,2,3]
29+
输出: "onetwothree"
30+
解释:
31+
有三个线程会被异步启动。
32+
输入 [1,2,3] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 two() 方法,线程 C 将会调用 three() 方法。
33+
正确的输出是 "onetwothree"。
34+
```
35+
36+
**示例 2:**
37+
38+
```
39+
输入: [1,3,2]
40+
输出: "onetwothree"
41+
解释:
42+
输入 [1,3,2] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 three() 方法,线程 C 将会调用 two() 方法。
43+
正确的输出是 "onetwothree"。
44+
```
45+
46+
### 解法
47+
48+
多线程同步问题,很好理解
49+
50+
#### CPP
51+
52+
```cpp
53+
class Foo { //C++ 11
54+
public:
55+
Foo() {
56+
_mutex1.lock();
57+
_mutex2.lock();
58+
}
59+
60+
void first(function<void()> printFirst) {
61+
62+
printFirst();
63+
_mutex1.unlock();
64+
}
65+
66+
void second(function<void()> printSecond) {
67+
68+
_mutex1.lock();
69+
printSecond();
70+
_mutex1.unlock();
71+
_mutex2.unlock();
72+
}
73+
74+
void third(function<void()> printThird) {
75+
76+
_mutex2.lock();
77+
printThird();
78+
_mutex2.unlock();
79+
}
80+
81+
82+
private:
83+
std::mutex _mutex1;
84+
std::mutex _mutex2;
85+
86+
};
87+
```
88+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
class Foo {
2+
public:
3+
Foo() {
4+
_mutex1.lock();
5+
_mutex2.lock();
6+
}
7+
8+
void first(function<void()> printFirst) {
9+
10+
printFirst();
11+
_mutex1.unlock();
12+
}
13+
14+
void second(function<void()> printSecond) {
15+
16+
_mutex1.lock();
17+
printSecond();
18+
_mutex1.unlock();
19+
_mutex2.unlock();
20+
}
21+
22+
void third(function<void()> printThird) {
23+
24+
_mutex2.lock();
25+
printThird();
26+
_mutex2.unlock();
27+
}
28+
29+
30+
private:
31+
std::mutex _mutex1;
32+
std::mutex _mutex2;
33+
34+
};
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
## 1115.交替打印FooBar
2+
### 问题描述
3+
4+
我们提供一个类:
5+
6+
```
7+
class FooBar {
8+
public void foo() {
9+
for (int i = 0; i < n; i++) {
10+
print("foo");
11+
}
12+
}
13+
14+
public void bar() {
15+
for (int i = 0; i < n; i++) {
16+
print("bar");
17+
}
18+
}
19+
}
20+
```
21+
22+
两个不同的线程将会共用一个 `FooBar` 实例。其中一个线程将会调用 `foo()` 方法,另一个线程将会调用 `bar()` 方法。
23+
24+
请设计修改程序,以确保 "foobar" 被输出 n 次。
25+
26+
27+
28+
**示例 1:**
29+
30+
```
31+
输入: n = 1
32+
输出: "foobar"
33+
解释: 这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法,"foobar" 将被输出一次。
34+
```
35+
36+
**示例 2:**
37+
38+
```
39+
输入: n = 2
40+
输出: "foobarfoobar"
41+
解释: "foobar" 将被输出两次。
42+
```
43+
44+
45+
46+
### 思路
47+
48+
两锁交替的同步,后进行的代码先加锁原则
49+
50+
```cpp
51+
class FooBar {
52+
private:
53+
int n;
54+
std::mutex _mutex1;
55+
std::mutex _mutex2;
56+
57+
public:
58+
FooBar(int n) {
59+
this->n = n;
60+
_mutex2.lock();
61+
}
62+
63+
void foo(function<void()> printFoo) {
64+
65+
for (int i = 0; i < n; i++) {
66+
_mutex1.lock();
67+
printFoo();
68+
_mutex2.unlock();
69+
}
70+
}
71+
72+
void bar(function<void()> printBar) {
73+
74+
for (int i = 0; i < n; i++) {
75+
_mutex2.lock();
76+
printBar();
77+
_mutex1.unlock();
78+
}
79+
}
80+
};
81+
```
82+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class FooBar {
2+
private:
3+
int n;
4+
std::mutex _mutex1;
5+
std::mutex _mutex2;
6+
7+
public:
8+
FooBar(int n) {
9+
this->n = n;
10+
_mutex2.lock();
11+
}
12+
13+
void foo(function<void()> printFoo) {
14+
15+
for (int i = 0; i < n; i++) {
16+
_mutex1.lock();
17+
printFoo();
18+
_mutex2.unlock();
19+
}
20+
}
21+
22+
void bar(function<void()> printBar) {
23+
24+
for (int i = 0; i < n; i++) {
25+
_mutex2.lock();
26+
printBar();
27+
_mutex1.unlock();
28+
}
29+
}
30+
};
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
## 1116.Print Zero Even Odd(leetcode未翻译)
2+
### 问题描述
3+
4+
Suppose you are given the following code:
5+
6+
```
7+
class ZeroEvenOdd {
8+
public ZeroEvenOdd(int n) { ... } // constructor
9+
public void zero(printNumber) { ... } // only output 0's
10+
public void even(printNumber) { ... } // only output even numbers
11+
public void odd(printNumber) { ... } // only output odd numbers
12+
}
13+
```
14+
15+
The same instance of `ZeroEvenOdd` will be passed to three different threads:
16+
17+
1. Thread A will call `zero()` which should only output 0's.
18+
2. Thread B will call `even()` which should only ouput even numbers.
19+
3. Thread C will call `odd()` which should only output odd numbers.
20+
21+
Each of the thread is given a `printNumber` method to output an integer. Modify the given program to output the series `010203040506`... where the length of the series must be 2*n*.
22+
23+
24+
25+
**Example 1:**
26+
27+
```
28+
Input: n = 2
29+
Output: "0102"
30+
Explanation: There are three threads being fired asynchronously. One of them calls zero(), the other calls even(), and the last one calls odd(). "0102" is the correct output.
31+
```
32+
33+
**Example 2:**
34+
35+
```
36+
Input: n = 5
37+
Output: "0102030405"
38+
```
39+
40+
41+
42+
### 思路
43+
44+
一个同步问题,一个互斥问题,奇偶打印是互斥,0和奇/偶的打印是同步问题,所以用到3把锁
45+
46+
```cpp
47+
class ZeroEvenOdd {
48+
private:
49+
int n;
50+
int flag;
51+
mutex m1,m2,m3;
52+
53+
public:
54+
ZeroEvenOdd(int n) {
55+
this->n = n;
56+
flag = 1; //奇偶判断
57+
m1.lock();
58+
m2.lock();
59+
m3.lock();
60+
}
61+
62+
// printNumber(x) outputs "x", where x is an integer.
63+
void zero(function<void(int)> printNumber) {
64+
m3.unlock();
65+
for(int i = 0; i < n ;i++){
66+
m3.lock();
67+
printNumber(0);
68+
if(flag == 1)flag = 0,m2.unlock();
69+
else flag = 1,m1.unlock();
70+
}
71+
}
72+
73+
74+
void odd(function<void(int)> printNumber) { //输出奇数
75+
for(int i = 1;i <= n; i+=2){
76+
m2.lock();
77+
printNumber(i);
78+
m3.unlock();
79+
}
80+
}
81+
82+
void even(function<void(int)> printNumber) { //输出偶数
83+
for(int i = 2;i <= n; i+=2){
84+
m1.lock();
85+
printNumber(i);
86+
m3.unlock();
87+
}
88+
}
89+
};
90+
```
91+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
class ZeroEvenOdd {
2+
private:
3+
int n;
4+
int flag;
5+
mutex m1,m2,m3;
6+
7+
public:
8+
ZeroEvenOdd(int n) {
9+
this->n = n;
10+
flag = 1; //奇偶判断
11+
m1.lock();
12+
m2.lock();
13+
m3.lock();
14+
}
15+
16+
// printNumber(x) outputs "x", where x is an integer.
17+
void zero(function<void(int)> printNumber) {
18+
m3.unlock();
19+
for(int i = 0; i < n ;i++){
20+
m3.lock();
21+
printNumber(0);
22+
if(flag == 1)flag = 0,m2.unlock();
23+
else flag = 1,m1.unlock();
24+
}
25+
}
26+
27+
28+
void odd(function<void(int)> printNumber) { //输出奇数
29+
for(int i = 1;i <= n; i+=2){
30+
m2.lock();
31+
printNumber(i);
32+
m3.unlock();
33+
}
34+
}
35+
36+
void even(function<void(int)> printNumber) { //输出偶数
37+
for(int i = 2;i <= n; i+=2){
38+
m1.lock();
39+
printNumber(i);
40+
m3.unlock();
41+
}
42+
}
43+
};

0 commit comments

Comments
 (0)