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”錯(cuò)誤頁(yè)面
-瀏覽器以外訪問返回JSON串:
{"timestamp":1487060396727,
"status":404,
"error":"Not Found",
"message":"No message available",
"path":"/test"}
Kafka消息隊(duì)列
Kafka是分布式的發(fā)布—訂閱消息系統(tǒng)
高吞吐量:可以滿足每秒百萬(wàn)級(jí)別消息的生產(chǎn)和消費(fèi)——生產(chǎn)消費(fèi)。
持久性:有一套完善的消息存儲(chǔ)機(jī)制,確保數(shù)據(jù)的高效安全的持久化。
分布式:基于分布式的擴(kuò)展和容錯(cuò)機(jī)制;Kafka的數(shù)據(jù)都會(huì)復(fù)制到幾臺(tái)服務(wù)器上。當(dāng)某一臺(tái)故障失效時(shí),生產(chǎn)者和消費(fèi)者轉(zhuǎn)而使用其它的機(jī)器。
- 基本概念:
發(fā)送消息者成為Producer,消息接受者成為Consumer;
kafka對(duì)消息保存時(shí)根據(jù)Topic進(jìn)行歸類,每一類的消息稱之為一個(gè)主題(Topic),消費(fèi)者可以只關(guān)注自己需要的Topic中的消息;
此外kafka集群有多個(gè)kafka實(shí)例組成,每個(gè)實(shí)例稱為broker,消息代理,Kafka集群中的一個(gè)kafka服務(wù)節(jié)點(diǎn)稱為一個(gè)broker,主要存儲(chǔ)消息數(shù)據(jù);

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

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

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

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