wait 為什么一定要跟著synchronized???
wait()的作用是讓“當(dāng)前線程”等待,而“當(dāng)前線程”是指正在cpu上運(yùn)行的線程!
websocket協(xié)議
Mysql 擁有者變更的解決方案
去終端執(zhí)行:
sudo chown -R mysql /usr/local/mysql/data
sleep與wait的區(qū)別
1、sleep是Thread的靜態(tài)類方法,即使在a線程里調(diào)用了b的sleep方法,實(shí)際上還是a去睡覺,要讓b線程睡覺要在b的代碼中調(diào)用sleep。
2、最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
3、sleep不出讓系統(tǒng)資源,占著CPU睡覺;wait是進(jìn)入線程等待池等待,出讓系統(tǒng)資源,其他線程可以占用CPU
Spring Boot默認(rèn)開啟異常應(yīng)答
-瀏覽器訪問,返回“Whitelabel Error Page”錯誤頁面
-瀏覽器以外訪問返回JSON串:
{"timestamp":1487060396727,
"status":404,
"error":"Not Found",
"message":"No message available",
"path":"/test"}
Kafka消息隊(duì)列
Kafka是分布式的發(fā)布—訂閱消息系統(tǒng)
高吞吐量:可以滿足每秒百萬級別消息的生產(chǎn)和消費(fèi)——生產(chǎn)消費(fèi)。
持久性:有一套完善的消息存儲機(jī)制,確保數(shù)據(jù)的高效安全的持久化。
分布式:基于分布式的擴(kuò)展和容錯機(jī)制;Kafka的數(shù)據(jù)都會復(fù)制到幾臺服務(wù)器上。當(dāng)某一臺故障失效時,生產(chǎn)者和消費(fèi)者轉(zhuǎn)而使用其它的機(jī)器。
- 基本概念:
發(fā)送消息者成為Producer,消息接受者成為Consumer;
kafka對消息保存時根據(jù)Topic進(jìn)行歸類,每一類的消息稱之為一個主題(Topic),消費(fèi)者可以只關(guān)注自己需要的Topic中的消息;
此外kafka集群有多個kafka實(shí)例組成,每個實(shí)例稱為broker,消息代理,Kafka集群中的一個kafka服務(wù)節(jié)點(diǎn)稱為一個broker,主要存儲消息數(shù)據(jù);

對于offset的保存和使用,由consumer來控制;當(dāng)consumer正常消費(fèi)消息時,offset將會"線性"的向前驅(qū)動,即消息將依次順序被消費(fèi)。事實(shí)上consumer可以使用任意順序消費(fèi)消息,它只需要將offset重置為任意值。
即使消息被消費(fèi),消息仍然不會被立即刪除。日志文件將會根據(jù)broker中的配置要求,保留一定的時間之后刪除。
在發(fā)布-訂閱模型中,消息被廣播給所有的消費(fèi)者,接收到消息的消費(fèi)者都可以處理此消息。
每個partition都有一個server(即kafka實(shí)例)為"leader",leader負(fù)責(zé)所有的讀寫操作,而follower被動的復(fù)制數(shù)據(jù)。如果leader宕機(jī),其它的一個follower會被推舉為新的leader。 一臺服務(wù)器可能同時是一個分區(qū)的leader,另一個分區(qū)的follower。
一個partition中的消息只會被group中的一個consumer消費(fèi)。

與Spring的集成
未完待續(xù)
Zookeeper

Zookeeper設(shè)計(jì)目的:
1.最終一致性:client不論連接到哪個Server,展示給它都是同一個視圖。
2.可靠性:如果消息被到一臺服務(wù)器接受,那么它將被所有的服務(wù)器接受。
命名服務(wù)
在zookeeper的文件系統(tǒng)里創(chuàng)建一個目錄,即有唯一的path。配置管理
如果程序分散部署在多臺機(jī)器上,要逐個改變配置就變得困難。現(xiàn)在把這些配置全部放到zookeeper上去,保存在 Zookeeper 的某個目錄節(jié)點(diǎn)中,然后所有相關(guān)應(yīng)用程序?qū)@個目錄節(jié)點(diǎn)進(jìn)行監(jiān)聽,一旦配置信息發(fā)生變化,每個應(yīng)用程序就會收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置信息應(yīng)用到系統(tǒng)中就好集群角色
一個 ZooKeeper 集群同一時刻只會有一個 Leader,其他都是 Follower 或 Observer(默認(rèn)不存在觀察者)。
Spring eureka 服務(wù)治理

Eureka Server: 服務(wù)注冊中心,負(fù)責(zé)服務(wù)列表的注冊、維護(hù)和查詢等功能;
Service Provider: 服務(wù)提供方,同時也是一個Eureka Client,負(fù)責(zé)將所提供的服務(wù)向Eureka Server進(jìn)行注冊、續(xù)約和注銷等操作。注冊時所提供的主要數(shù)據(jù)包括服務(wù)名、機(jī)器ip、端口號、域名等,從而能夠使服務(wù)消費(fèi)方能夠找到;
Service Consumer: 服務(wù)消費(fèi)方,同時也是一個Eureka Client。
什么時候加Synchronized鎖
public class Thread1 implements Runnable {
public void run() {
synchronized(this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
}
}
}
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread ta = new Thread(t1, "A");
Thread tb = new Thread(t1, "B");
ta.start();
tb.start();
}
當(dāng)兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內(nèi)只能有一個線程得到執(zhí)行。
public synchronized void methodA(int a, int b) {
};
public synchronized void methodB(int a){
methodA(a, 0);
}
//注意:鎖住的是Test的實(shí)例t
Test t = new Test();
t.methodB();
鎖住的是Test的實(shí)例t
當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結(jié)果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。
但是其它線程還是可以訪問該被鎖住的Object中的非Synchronized實(shí)例
什么時候需要加Synchronized鎖:
如果有一塊代碼(或方法)可能被多個線程同時訪問,然后里面操作的數(shù)據(jù)修改操作可能因?yàn)椴煌€程的操作而不一致的時候,使用synchronized鎖定這塊代碼,確保同時只有一個線程訪問這個代碼塊。
Spring cloud Stream
消息發(fā)送
public void createOrder(MemberOrder order) {
CommonMO mo = new CommonMO();
mo.setMsg("newOrder");
mo.setData(order);
ordersSource.memberOrders().send(MessageBuilder.withPayload(mo).build());
}
會往memberOrders信道里發(fā)送流
public interface MemberOrdersSink {
String ORDERS = "memberOrders";
@Input
SubscribableChannel memberOrders();
}
@EnableBinding(MemberOrdersSink.class)
public class MemberOrdersMsgReceiver {
@StreamListener(MemberOrdersSink.ORDERS)
public void recordOrder(CommonMO mo) {
}
再探ReentrantLock 與 Condition
線程級別的定時任務(wù)
ScheduledExecutorService與Executors都是java.concurrent.util包下的
建議手動創(chuàng)建線程池
//線程級別的定時任務(wù)
public void timer() {
// Calendar c = Calendar.getInstance();
// c.set(Calendar.HOUR_OF_DAY, 10); // 控制時
// c.set(Calendar.MINUTE, 0); // 控制分
// c.set(Calendar.SECOND, 0); // 控制秒
//
// Date time = c.getTime(); // 得到執(zhí)行任務(wù)的時間,此處為當(dāng)天的10:00:00
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
sendHeartBeat();
}
}, 100,7000, TimeUnit.MILLISECONDS);// 這里設(shè)定將延時每隔1000毫秒執(zhí)行一次
}
如何正確的終止線程
為何不用stop
stop()方法太過于暴力,會強(qiáng)行把執(zhí)行一半的線程終止。這樣會就不會保證線程的資源正確釋放,通常是沒有給與線程完成資源釋放工作的機(jī)會.
停掉一個線程將會導(dǎo)致所有已鎖定的監(jiān)聽器被解鎖,這個之前被監(jiān)聽器鎖定的對象被解鎖,其他線程就能隨意操作這個對象,將導(dǎo)致任何可能的結(jié)果。
官方給出的網(wǎng)頁說明了不能捕獲ThreadDeath異常并修復(fù)對象的
yield
使當(dāng)前線程從執(zhí)行狀態(tài)(運(yùn)行狀態(tài))變?yōu)?strong>可執(zhí)行態(tài)(就緒狀態(tài))。cpu會從眾多的可執(zhí)行態(tài)里選擇,
用了yield方法后,該線程就會把CPU時間讓掉,讓其他或者自己的線程執(zhí)行
Java反射定義、獲取Class三種方法
反射機(jī)制的定義:
在運(yùn)行狀態(tài)時(動態(tài)的),對于任意一個類,都能夠得到這個類的所有屬性和方法。
對于任意一個對象,都能夠調(diào)用它的任意屬性和方法。
Class類是反射機(jī)制的起源,我們得到Class類對象有3種方法:
第一種:通過類名獲得
Class<?> class = ClassName.class;
第二種:通過類名全路徑獲得:
Class<?> class = Class.forName("類名全路徑");
第三種:通過實(shí)例對象獲得:
Class<?> class = object.getClass();
JDK 動態(tài)代理
Java IO 題目
JAVA NIO
Java int 32位
C++ int
int 4 float 4
long 4 double 8