面试复盘

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

 

posted @ 2022-10-09 19:54  人在江湖之诗和远方  阅读(19)  评论(0编辑  收藏  举报