0%

面试题-算法-LeetCode-多线程

1114、按序打印:类中的3个方法分别运行在3个线程中,如何保证它们按顺序执行?

点击看答案

没找到方便记忆的版本,自己写个。当然,链接中通过 AtomInteger 来实现自旋也是不错的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class JavaMainClass {

volatile int a = 0;
void test1(){
System.out.println("test1");
a = 1;
}
void test2(){
while (a != 1){
Thread.yield();
}
System.out.println("test2");
a= 2;
}
void test3(){
while (a != 2){
Thread.yield();
}
System.out.println("test3 \n");
}
}

自己写的时候的问题:看懂题目,volatile 关键字使用即可

LeetCode

1195、 交替打印字符串

编写一个可以从 1 到 n 输出代表这个数字的字符串的程序,但是:

  • 如果这个数字可以被 3 整除,输出 “fizz”。
  • 如果这个数字可以被 5 整除,输出 “buzz”。
  • 如果这个数字可以同时被 3 和 5 整除,输出 “fizzbuzz”。

假设有这么一个类:

1
2
3
4
5
6
7
class FizzBuzz {
  public FizzBuzz(int n) { ... }  // constructor
public void fizz(printFizz) { ... } // only output "fizz"
public void buzz(printBuzz) { ... } // only output "buzz"
public void fizzbuzz(printFizzBuzz) { ... } // only output "fizzbuzz"
public void number(printNumber) { ... } // only output the numbers
}
点击看答案

看参考答案吧

自己写的时候的问题:使用Semaphore 关键字会简单很多,使用volatile 关键字稍稍麻烦些。

这个问题也可以关联到后续的 打印零与奇偶数

LeetCode

1115、 交替打印FooBar

我们提供一个类:

1
2
3
4
5
6
7
8
9
10
11
12
13
class FooBar {
public void foo() {
    for (int i = 0; i < n; i++) {
      print("foo");
  }
}

public void bar() {
    for (int i = 0; i < n; i++) {
      print("bar");
    }
}
}

两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。请设计修改程序,以确保 “foobar” 被输出 n 次。

点击看答案

注意在空闲的时候Thread.yield()

自己写的时候的问题:可以使用 volatile 关键字,不过在 while 自旋过程中,需要 Thread.yield(); 让出cpu,否则容易出现超时。

LeetCode

1226、 哲学家进餐

点击看答案

这个问题还没想通,后续再看

LeetCode

H2O 生成

点击看答案

使用 Semaphore简单粗暴。这个问题还没想通,后续再看

自己写的时候的问题:看别人的再自己写的,h的Semaphore(2),而 o 的 Semaphore(0) ,但是生成h 一个 就release一个 o (虽然o的permit 数量为 0 ,但是在另一个线程release 一个就相当于create 一个,所以并不矛盾,同理,在生成 o 的时候, o.acquire(2))

LeetCode

谢谢你的鼓励