1.手寫一個生產者消費者模型?
查了一下,這篇講的是最好的!一共有三種方式,阻塞隊列,synchronized的,lock的
最簡單的一個,基於阻塞隊列的:
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
public class producerByBq {
private static final int CAPACITY = 5;
public static void main(String[] args)
{
LinkedBlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<Integer>(CAPACITY);
Thread producer1 = new producer("P-1", blockingQueue);
Thread producer2 = new producer("P-2", blockingQueue);
Thread consumer1 = new consumer("C1", blockingQueue);
Thread consumer2 = new consumer("C2", blockingQueue);
Thread consumer3 = new consumer("C3", blockingQueue);
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
consumer3.start();
}
public static class producer extends Thread
{
private LinkedBlockingQueue<Integer> blockingQueue;
private String name;
private int i=0;
public producer(String name,LinkedBlockingQueue<Integer> blockingQueue)
{
//這個supername是幹什麼的
super(name);
this.blockingQueue=blockingQueue;
this.name=name;
}
public void run()
{
while(true)
{
try {
blockingQueue.put(i);
System.out.println("[" + name + "] Producing value : +" + i);
i++;
Thread.sleep(new Random().nextInt(1000));
}catch (Exception e)
{
e.printStackTrace();
}
}
}
}
public static class consumer extends Thread
{
private LinkedBlockingQueue<Integer> blockingQueue;
private String name;
public consumer(String name,LinkedBlockingQueue<Integer> blockingQueue)
{
super(name);
this.blockingQueue=blockingQueue;
this.name=name;
}
public void run()
{
while(true)
{
try {
int x=blockingQueue.take();
System.out.println("[" + name + "] Consuming : " + x);
Thread.sleep(new Random().nextInt(1000));
}catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
第二個,基於synchronized的
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
public class producerBySyn {
private static final int CAPACITY = 5;
public static void main(String[] args)
{
Queue<Integer> queue = new LinkedList<Integer>();
Thread producer1 = new producer("P-1", queue,CAPACITY);
Thread producer2 = new producer("P-2", queue,CAPACITY);
Thread consumer1 = new consumer("C1", queue);
Thread consumer2 = new consumer("C2", queue);
Thread consumer3 = new consumer("C3", queue);
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
consumer3.start();
}
public static class producer extends Thread
{
private final Queue<Integer> queue;
private String name;
private int maxSize;
private int i=0;
public producer(String name,Queue<Integer> queue,int maxSize)
{
super(name);
this.queue=queue;
this.name=name;
this.maxSize=maxSize;
}
public void run()
{
while(true)
{
synchronized (queue)
{
while(queue.size()==maxSize)
{
try {
System.out .println("Queue is full, Producer[" + name + "] thread waiting for " + "consumer to take something from queue.");
queue.wait();
}catch (Exception e)
{
e.printStackTrace();
}
}
System.out.println("[" + name + "] Producing value : +" + i);
queue.offer(i++);
queue.notifyAll();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static class consumer extends Thread
{
private final Queue<Integer> queue;
private String name;
public consumer(String name,Queue<Integer> queue)
{
super(name);
this.queue=queue;
this.name=name;
}
public void run()
{
while(true)
{
synchronized (queue)
{
while(queue.size()==0)
{
try {
System.out.println("Queue is empty, Consumer[" + name + "] thread is waiting for Producer");
queue.wait();
}catch (Exception e)
{
e.printStackTrace();
}
}
int x = queue.poll();
System.out.println("[" + name + "] Consuming value : " + x);
queue.notifyAll();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
第三個,基於Lock和condition的
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class producerByLock {
private static final int CAPACITY = 5;
private static final Lock lock = new ReentrantLock();
private static final Condition fullCondition = lock.newCondition(); //隊列滿的條件
private static final Condition emptyCondition = lock.newCondition(); //隊列空的條件
public static void main(String[] args)
{
Queue<Integer> queue = new LinkedList<Integer>();
Thread producer1 = new producer("P-1", queue,CAPACITY);
Thread producer2 = new producer("P-2", queue,CAPACITY);
Thread consumer1 = new consumer("C1", queue);
Thread consumer2 = new consumer("C2", queue);
Thread consumer3 = new consumer("C3", queue);
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
consumer3.start();
}
public static class producer extends Thread
{
private final Queue<Integer> queue;
private String name;
private int maxSize;
private int i=0;
public producer(String name,Queue<Integer> queue,int maxSize)
{
super(name);
this.queue=queue;
this.name=name;
this.maxSize=maxSize;
}
public void run()
{
while(true)
{
lock.lock();
while(queue.size() == maxSize){
try {
System.out .println("Queue is full, Producer[" + name + "] thread waiting for " + "consumer to take something from queue.");
//條件不滿足,生產阻塞
fullCondition.await();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("[" + name + "] Producing value : +" + i);
queue.offer(i++);
//喚醒其他所有生產者、消費者
fullCondition.signalAll();
emptyCondition.signalAll();
//釋放鎖
lock.unlock();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static class consumer extends Thread
{
private final Queue<Integer> queue;
private String name;
public consumer(String name,Queue<Integer> queue)
{
super(name);
this.queue=queue;
this.name=name;
}
public void run()
{
while(true)
{
lock.lock();
while(queue.isEmpty()){
try {
System.out.println("Queue is empty, Consumer[" + name + "] thread is waiting for Producer");
//條件不滿足,消費阻塞
emptyCondition.await();
} catch (Exception ex) {
ex.printStackTrace();
}
}
int x = queue.poll();
System.out.println("[" + name + "] Consuming value : " + x);
//喚醒其他所有生產者、消費者
fullCondition.signalAll();
emptyCondition.signalAll();
//釋放鎖
lock.unlock();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
2.Java多線程notify/notifyAll喚醒的是誰?
參考:https://blog.csdn.net/q5706503/article/details/84591159
3.什麼是時間片輪轉?
時間片輪轉說的是操作系統的一種調度算法,用於交互式系統,每一個進程都給分配一個時間片,然後進行快速的切換,但是速度很快,人看不到這些切換。另外還有優先級調度算法,多級反饋隊列算法(既有優先級又有時間片)
4.什麼是分佈式事務?
參考:https://blog.csdn.net/bjweimengshu/article/details/79607522
分佈式事務用於在分佈式系統中保證不同節點之間的數據一致性。
XA兩階段提交:
(1)在XA分佈式事務的第一階段,作爲事務協調者的節點會首先向所有的參與者節點發送Prepare請求。在接到Prepare請求之後,每一個參與者節點會各自執行與事務有關的數據更新,寫入Undo Log和Redo Log。如果參與者執行成功,暫時不提交事務,而是向事務協調節點返回“完成”消息。當事務協調者接到了所有參與者的返回消息,整個分佈式事務將會進入第二階段。
(2)作爲事務協調者的節點給所有事務參與者發出Commit請求。接到Commit請求之後,事務參與者節點會各自進行本地的事務提交,並釋放鎖資源。當本地事務完成提交後,將會向事務協調者返回“完成”消息。當事務協調者接收到所有事務參與者的“完成”反饋,整個分佈式事務完成。
在XA的第一階段,如果某個事務參與者反饋失敗消息,說明該節點的本地事務執行不成功,必須回滾。
於是在第二階段,事務協調節點向所有的事務參與者發送Abort請求。接收到Abort請求之後,各個事務參與者節點需要在本地進行事務的回滾操作,回滾操作依照Undo Log來進行。
5.常見的負載均衡算法?
(1)輪詢
將所有請求,依次分發到每臺服務器上,適合服務器硬件相同的場景。
優點:服務器請求數目相同;
缺點:服務器壓力不一樣,不適合服務器配置不同的情況;
(2)隨機
請求隨機分配到各臺服務器上。
優點:使用簡單;
缺點:不適合機器配置不同的場景
(3)最少鏈接
將請求分配到連接數最少的服務器上(目前處理請求最少的服務器)。
優點:根據服務器當前的請求處理情況,動態分配;
缺點:算法實現相對複雜,需要監控服務器請求連接數;
(4)Hash(源地址散列)
根據IP地址進行Hash計算,得到IP地址。
優點:將來自同一IP地址的請求,同一會話期內,轉發到相同的服務器;實現會話粘滯。
缺點:目標服務器宕機後,會話會丟失;
(5)加權
在輪詢,隨機,最少鏈接,Hash等算法的基礎上,通過加權的方式,進行負載服務器分配。
優點:根據權重,調節轉發服務器的請求數目;
缺點:使用相對複雜;