Skip to content

Code-工程问题

Updated: at 04:12 PM

🤠Code-工程问题

1. Java工程

1.1. 并发编程

1.1.1. Java实现阻塞队列

一个full Condition和一个empty Condition

注意这两个队列的await()要用while包起来

import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyArrayBlockingQueue {
    int size = 50;
    Lock lock = new ReentrantLock();
    Condition empty = lock.newCondition();
    Condition full = lock.newCondition();

    Deque queue = new LinkedList();

    void offer(Object object) {
        lock.lock();
        try {
            while(queue.size() == size) {
                empty.await();
            }
            queue.add(object);
            full.signal();
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    Object poll() {
        lock.lock();
        try {
            while(queue.isEmpty()) {
                full.await();
            }
            Object res = queue.pollFirst();
            empty.signal();
            return res;
        } catch(Exception e) {
            return null;
        } finally {
            lock.unlock();
        }
    }
}

1.1.2. 手撕死锁

线程1需要获取锁1,然后获取锁2,需要等待线程2释放锁2

线程2需要获取锁2,然后获取锁1,需要等待线程1释放锁1

public class MyDeadLock {
    Object resource1 = new Object();
    Object resource2 = new Object();
    public void deadLockTest() {
        new Thread(() ->{
            synchronized (resource1) {
                System.out.println("get resource1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("waiting for resource2");
                synchronized(resource2) {
                    System.out.println("get resource2 success!");
                }
            }
        }).start();
        new Thread(() -> {
            synchronized (resource2) {
                System.out.println("get resource2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("waiting for resource1");
                synchronized(resource1) {
                    System.out.println("get resource1 success!");
                }
            }
        }).start();
    }
}

1.1.3. Java三个线程打印ABC

都有个await和notify,用于等待下一轮满足当前条件和唤醒下一个

synchronized和wait/notify实现

pre和cur都获取到锁才行(保证顺序性)

public class MyPrintABC {

    public class PrintThread implements Runnable{

        String name;
        Object pre;
        Object cur;
        PrintThread(String name, Object pre, Object cur) {
            this.name = name;
            this.pre = pre;
            this.cur = cur;
        }
        @Override
        public void run() {
            int count = 10;
            while(count > 0) {
                synchronized (pre) {
                    synchronized (cur) {
                        System.out.print(name);
                        count--;
                        cur.notifyAll();
                    }

                    try {
                        pre.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }

        }
    }

    public void printBySyn() {
        Object obj1 = new Object();
        Object obj2 = new Object();
        Object obj3 = new Object();
        PrintThread printThread1 = new PrintThread("a", obj3, obj1);
        PrintThread printThread2 = new PrintThread("b", obj1, obj2);
        PrintThread printThread3 = new PrintThread("c", obj2, obj3);
        new Thread(printThread1).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(printThread2).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(printThread3).start();
    }
}
ReentrantLock和Condition实现

相比于synchronized保证顺序性用的cnt%3

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyPrintABCByLock {
    int cnt = 0;
    public void printABCByLock() {
        Lock lock = new ReentrantLock();
        Condition a = lock.newCondition();
        Condition b = lock.newCondition();
        Condition c = lock.newCondition();
        new Thread(() -> {
            try {
                lock.lock();
                for(int i = 0; i < 10; ++i) {
                    while(cnt % 3 != 0) {
                        try {
                            a.await();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.print("a");
                    cnt++;
                    b.signal();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(() -> {
            try {
                lock.lock();
                for(int i = 0; i < 10; ++i) {
                    while(cnt % 3 != 1) {
                        try {
                            b.await();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.print("b");
                    cnt++;
                    c.signal();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(() -> {
            try {
                lock.lock();
                for(int i = 0; i < 10; ++i) {
                    while(cnt % 3 != 2) {
                        try {
                            c.await();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.print("c");
                    cnt++;
                    a.signal();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }).start();
    }
}

1.2. 设计模式

1.2.1. Java懒汉式双重检测锁?

双重检查是因为可能会有指令重排序导致的创建多次(可能两个线程进入synchronized判读为null)

public class LazyDoubleCheckSingleton {
    private LazyDoubleCheckSingleton(){};
    private static volatile LazyDoubleCheckSingleton singleton;
    private static LazyDoubleCheckSingleton getSingleton() {
        if(singleton == null) {
            synchronized (LazyDoubleCheckSingleton.class) {
                if(singleton == null) {
                    singleton = new LazyDoubleCheckSingleton();
                }
            }
        }
        return singleton;
    }
}

1.2.2. Java懒汉式实现单例模式

public class HungrySingleton {
    private static HungrySingleton singleton = new HungrySingleton();
    private HungrySingleton(){}
    public static HungrySingleton getSingleton() {
        return singleton;
    }
}

1.2.3. 静态内部类实现单例模式

public class StaticInnerClassSingleton {
    private StaticInnerClassSingleton(){}
    private static class SingletonHolder{
        private static final StaticInnerClassSingleton singleton = new StaticInnerClassSingleton();
    }
    public static StaticInnerClassSingleton getInstance() {
        return SingletonHolder.singleton;
    }
}