文章目錄
- 部落格概述
- 具體代碼
- threadlocal
- 單例模式
- 餓漢式
- 懶漢式
- 靜态内部類
- 雙重檢查鎖
部落格概述
本文對threalocal關鍵字和單例模式的正常騷操作進行了代碼示例,并且進行了一些自己個人角度了解的說明。
具體代碼
threadlocal
public class ConnThreadLocal {
public static ThreadLocal<String> th = new ThreadLocal<String>();
public void setTh(String value){
th.set(value);
}
public void getTh(){
System.out.println(Thread.currentThread().getName() + ":" + this.th.get());
}
public static void main(String[] args) throws InterruptedException {
final ConnThreadLocal ct = new ConnThreadLocal();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
ct.setTh("張三");
ct.getTh();
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
ct.getTh();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t2");
t1.start();
t2.start();
}
}
threadlocal是線程局部變量,是一種多線程間并發通路的解決方案。與sync加鎖的方式不同,threadlocal完全不提供鎖,而是使用空間換時間的手段,為每個線程提供變量的獨立副本,以保障線程安全。從性能上說,threadlocal不具有絕對的優勢,,在并發不是很高的時候,加鎖的性能會更好,但作為一套與鎖完全無關的線程安全解決方案,在高并發量或者競争激烈的場景,使用threadlocal可以一定程度上減少競争。這種無鎖的方案,一個線程使用一個變量的場景适用,一旦出現多線程讀取相同變量的業務邏輯,就不适用了。一些架構如struts,spring都使用了這種技術。使用了map對象,然後key是線程ID。對上面這個例子,th對象是互相不可見的。
單例模式
單例模式有正常的5種形态,餓漢式,懶漢式,雙重檢查鎖,靜态内部類,枚舉。這裡給出前四種的寫法。
餓漢式
在餓漢式中static變量會在類加載時初始化,此時也不會涉及多個線程對象通路該對象的問題,虛拟機保證隻會裝載一次這個類,肯定不會發生并發通路的問題 ,是以可以省略sync關鍵字。
package instance;
/**
* @Auther: ;李澤
* @Date: 2019/3/27 22:20
* @Description:
*/
public class SingletonDemo1 {
//類初始化的時候,立即加載這個對象(沒有延時加載的優勢),加載類時,天然是線程無關的。
private static SingletonDemo1 instance = new SingletonDemo1();
private SingletonDemo1(){
}
//方法沒有同步調用效率高
public static SingletonDemo1 getInstance() {
return instance;
}
}
懶漢式
package instance;
/**
* @Auther: ;李澤
* @Date: 2019/3/27 22:46
* @Description:
*/
public class SingletonDemo2 {
//類初始化的時候,立即加載這個對象(沒有延時加載的優勢),加載類時,天然是線程無關的。
private static SingletonDemo2 instance = new SingletonDemo2();
private SingletonDemo2(){
}
public synchronized static SingletonDemo2 getInstance() {
return instance==null?new SingletonDemo2():instance;
}
}
靜态内部類
/**
* @Auther: ;李澤
* @Date: 2019/3/27 22:49
* @Description:
*/
public class SingletonDemo3 {
private static class Singleton{
private static Singleton singleton = new Singleton();
}
public static Singleton getInstance() {
return Singleton.singleton;
}
}
雙重檢查鎖
package instance;
/**
* @Auther: ;李澤
* @Date: 2019/3/27 22:51
* @Description:
*/
public class SingletonDemo4 {
private static SingletonDemo4 demo4;
public static SingletonDemo4 getInstance() {
if(demo4 == null){
synchronized (SingletonDemo4.class){
if (demo4 == null){
demo4 = new SingletonDemo4();
}
}
}
return demo4;
}
}