面试复盘
1、写一个死锁
java
package Thread; /* * 死锁产生条件:多线程,多个锁,锁嵌套*/ public class DeadLockDemo { public static void main(String[] args) { //两个不同的锁对象 Object obj1=new Object(); Object obj2=new Object(); new Thread(new Runnable() { @Override public void run() { String name = Thread.currentThread().getName(); synchronized(obj1){//在拿到锁1的基础上去拿锁2 System.out.println(name+"拿到锁1,想要锁2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj2){ System.out.println(name+"拿到了锁2"); } } } },"线程A").start(); new Thread(new Runnable() { @Override public void run() { String name = Thread.currentThread().getName(); synchronized (obj2){//在拿到锁2的基础上去拿锁1 System.out.println(name+"拿到了锁2,想要锁1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(obj1){ System.out.println(name+"拿到了锁1"); } } } },"线程B").start(); } }
2、写一个生产消费模型
java
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * 使用 BlockQueue 实现生产者消费模型 */ public class BlockQueueTest { public static Integer count = 0; //创建一个阻塞队列 final BlockingQueue blockingQueue = new ArrayBlockingQueue<>(10); public static void main(String[] args) { BlockQueueTest testMain = new BlockQueueTest(); new Thread(testMain.new Producer()).start(); new Thread(testMain.new Consumer()).start(); } class Producer implements Runnable{ @Override public void run(){ for (int i = 0; i <10; i++) { try{ Thread.sleep(3000); }catch (Exception e){ e.printStackTrace(); } try{ blockingQueue.put(1); count++; System.out.println(Thread.currentThread().getName() + "生产者生产,目前总共有 " + count); }catch (InterruptedException e){ e.printStackTrace(); } } } } class Consumer implements Runnable{ @Override public void run(){ for (int i = 0; i <10; i++) { try{ Thread.sleep(3000); }catch (InterruptedException e){ e.printStackTrace(); } try{ blockingQueue.take();//消费 count--; System.out.println(Thread.currentThread().getName() + " 消费者消费,目前总共有 "+ count); }catch (InterruptedException e){ e.printStackTrace(); } } } } }
go:
package main
import "fmt"
func producer(out chan <- int) {
for i:=0; i<10; i++{
data := i*i
fmt.Println("生产者生产数据:", data)
out <- data // 缓冲区写入数据
}
close(out) //写完关闭管道
}
func consumer(in <- chan int){
// 无需同步机制,先做后做
// 没有数据就阻塞等
for data := range in {
fmt.Println("消费者得到数据:", data)
}
}
func main(){
// 传参的时候显式类型像隐式类型转换,双向管道向单向管道转换
ch := make(chan int, 5) // 添加缓冲区,5
go producer(ch) // 子go程作为生产者
consumer(ch) // 主go程作为消费者
}
打印奇偶数
public class Test01 {
private static int count;
private static final Object lock = new Object();
private static final int num = 100;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (count < num) {
synchronized (lock) {
if ((count % 2) == 0) {
System.out.println(Thread.currentThread().getName() + ":" + count);
count ++;
}
}
}
}
}, "偶数").start();
new Thread(new Runnable() {
@Override
public void run() {
while (count < num) {
synchronized (lock) {
if ((count % 2) == 1) {
System.out.println(Thread.currentThread().getName() + ":" + count);
count ++;
}
}
}
}
}, "奇数").start();
}
}
public class PrintOddEven2 {
private static int count = 0;
private static final Object object = new Object();
public static void main(String[] args) {
new Thread(new printer(), "偶数线程,").start();
new Thread(new printer(), "奇数线程,").start();
}
static class printer implements Runnable {
@Override
public void run() {
while (count <= 100) {
synchronized (object) {
// 打印数字,并立即释放锁
System.out.println(Thread.currentThread().getName() + "打印:" + count++);
object.notify();
// 此处判断,是为了打印完了100个数字后,程序能够正常结束,否则程序将一直等待下去,耗费系统资源。
if (count <= 100) {
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
go 交替打印
package main
import (
"fmt"
"sync"
)
// PrintOddAndEven1 /*
func PrintOddAndEven1() {
//方法一,使用无缓冲的channel进行通信
var wg = new(sync.WaitGroup) //注意这里需要是指针go语言当中都是值传递
wg.Add(2)
ch := make(chan struct{}) //无缓冲channel
defer close(ch)
maxVal := 100
go func() {
defer wg.Done()
for i := 1; i <= maxVal; i++ {
ch <- struct{}{}
if i%2 == 1 { //奇数
fmt.Printf("the odd is %d\n", i)
}
}
}()
go func() {
defer wg.Done()
for i := 1; i <= maxVal; i++ {
<-ch //从管道当中读取一个数据
if i%2 == 0 { //偶数
fmt.Printf("the even is %d\n", i)
}
}
}()
wg.Wait()
}
func main() {
PrintOddAndEven1()
fmt.Println("over")
}
交替打印字母数字
func main() {
numChan := make(chan struct{})
defer close(numChan)
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
for num := 1; num <= 26; num++ {
numChan <- struct{}{}
fmt.Printf("%d", num)
}
}()
go func() {
defer wg.Done()
for ch := 'A'; ch <= 'Z'; ch++ {
<-numChan
fmt.Printf("%s", string(ch))
}
}()
wg.Wait()
}
三个协程打印ABC
package main
import (
"fmt"
"sync"
)
func main() {
Achan := make(chan struct{}, 1)
Bchan := make(chan struct{}, 1)
Cchan := make(chan struct{}, 1)
defer close(Achan)
defer close(Bchan)
defer close(Cchan)
Achan <- struct{}{}
counter := 0
maxVal := 10
exitChan := make(chan struct{}) //用于退出
go func() {
for {
<-Achan
if counter >= maxVal {
exitChan <- struct{}{}
break
}
fmt.Printf("%s ", "A")
counter++
Bchan <- struct{}{}
}
}()
go func() {
for {
<-Bchan
if counter >= maxVal {
exitChan <- struct{}{}
break
}
fmt.Printf("%s ", "B")
counter++
Cchan <- struct{}{}
}
}()
go func() {
for {
<-Cchan
if counter >= maxVal {
exitChan <- struct{}{}
break
}
fmt.Printf("%s ", "C")
counter++
Achan <- struct{}{}
}
}()
<-exitChan
}
参考
https://blog.csdn.net/qq_56999918/article/details/129214882

浙公网安备 33010602011771号