并行模式與算法
- 單例模式 : 保證在系統(tǒng)中只生產(chǎn)一個實例。下面是幾種單例模式谎势。
private Single(){
System.out.println("Single is create");
}
private static Single single =new Single() ;
public static Single getInstance(){
return single ;
}
- 這個容易出現(xiàn)的問題就是單例什么時候創(chuàng)建的不受控制于未。 我們可以改造一下 :
public static int STATUS = 1 ;
private Single(){
System.out.println("Single is create");
}
private static Single single =new Single() ;
public static Single getInstance(){
return single ;
}
- 在原先的基礎(chǔ)上增加靜態(tài)成員夏跷。這樣在任何地方使用STATUS 都會導(dǎo)致instance 實例被創(chuàng)建闷旧。 不過 如果在我們new 對象的時候 沒有引用 STATUS 那么我們就會創(chuàng)建instance 實例。
- 接下來是一個懶加載的策略 城舞。核心思想是當(dāng)我們需要的時候才創(chuàng)建對象轩触。不過,為了方式多次創(chuàng)建對象我們不得不加鎖家夺,這樣就會導(dǎo)致在高并發(fā)的情況下 脱柱,引起鎖競爭。
private Single(){
System.out.println("Single is create");
}
private static Single single = null ;
public static Single getInstance(){
if(single == null)
single = new Single() ;
return single ;
}
- 上面兩者 結(jié)合的單例模式 : 思想是創(chuàng)建了一個內(nèi)部類拉馋,并且我們利用了虛擬機(jī)的類初始化機(jī)制創(chuàng)建單例榨为。
private Single(){
System.out.println("Single is create");
}
private static class SingleTonHolder{
private static Single instance = new Single();
}
public static Single getInstance(){
return SingleTonHolder.instance ;
}
不變模式:
- 主要使用場景需要滿足的條件:
- 當(dāng)對象創(chuàng)建后,其內(nèi)部狀態(tài)和數(shù)據(jù)不再發(fā)生任何變化煌茴。
- 對象需要被共享随闺,被多線程頻繁訪問。
- 為保證不變模式正常工作景馁,需要注意一下四點:
- 去除setter方法以及所有修改自身屬性的方法。
- 將所有屬性設(shè)置為私有逗鸣,并用final 標(biāo)記合住,確保不可修改绰精。
- 確保沒有子類可以重載修改他的行為。
- 有一個可以構(gòu)造完整對象的構(gòu)造函數(shù)透葛。
- java 中有很多元數(shù)據(jù)包裝類 都是使用的不變模式實現(xiàn)的笨使。
- String .
- Boolean.
- Byte .
- Character
- Double .
生產(chǎn)者- 消費者模式
生產(chǎn)者-消費者模式
//消費者
private BlockingQueue<PCdata> queue ;
private static final int SLEEPTIME = 1000 ;
public Consumer(BlockingQueue<PCdata> queue) {
this.queue = queue;
}
@Override
public void run() {
System.out.println("start Consumer id = "+ Thread.currentThread().getId());
Random random = new Random() ;
try {
while(true){
PCdata data = queue.take() ; // 會阻塞 如果沒有結(jié)果的話
if( null != data){
int re = data.getIntData() * data.getIntData();
System.out.println(MessageFormat.format("{0} * {1} ={2}",data.getIntData(),
data.getIntData(),re));
Thread.sleep(random.nextInt(SLEEPTIME));
}
}
} catch (Exception e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
//生產(chǎn)者
private volatile boolean isRunning = true ;
private BlockingQueue<PCdata> queue ;
private static AtomicInteger count = new AtomicInteger() ; //總數(shù) 原子操作類
private static final int SLEEPTIME = 100 ;
public Producer(BlockingQueue<PCdata> queue) {
super();
this.queue = queue;
}
@Override
public void run() {
PCdata data = null ;
Random random = new Random();
System.out.println(" start produceted id = "+ Thread.currentThread().getId());
try {
while(isRunning){
Thread.sleep(random.nextInt(SLEEPTIME));
data = new PCdata(count.incrementAndGet()); //構(gòu)造任務(wù)數(shù)據(jù)
System.out.println(data + "is put into queue");
if(!queue.offer(data,2,TimeUnit.SECONDS)){
System.err.println("filed to put data :"+ data);
}
}
} catch (Exception e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void stop(){
isRunning = false ;
}
}
//共享數(shù)據(jù)
private final int intData ;
public int getIntData() {
return intData;
}
public PCdata(int intData) {
super();
this.intData = intData;
}
@Override
public String toString() {
return "data:"+intData;
}