秦凱新技術社群推出的《Coding技術進階實戰》系列即將上線,包含語言類精深的用法和技巧,涵蓋 python,Java,Scala,Tensorflow等主流大資料和深度學習技術基礎,敬請期待。為什麼我會寫這樣一個系列,來源於被一位容器雲專家問到如何實現一個執行緒池時,讓我頓感以前研究的Java併發控制相關的理論以及多執行緒併發設計模式忘得九霄雲外,鑑於此,氣憤難平,決定展示個人程式設計魅力。
版權宣告:本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。QQ郵箱地址:1120746959@qq.com,如有任何技術交流,可隨時聯絡。
1 Scala 隱式轉換函式深入實踐
1.1 隱式轉換
要實現隱式轉換,只要程式可見的範圍內定義隱式轉換函式即可。Scala會自動使用隱式轉換函式。隱式轉換函式與普通函式唯一的語法區別就是,要以implicit開頭,而且最好要定義函式返回型別。
案例:特殊售票視窗(只接受特殊人群,比如學生、老人等)
詳解:當呼叫buySpecialTicket函式時,傳入引數Student不對照時,會進行隱式轉換為SpecialPerson
class SpecialPerson(val name: String)
class Student(val name: String)
class Older(val name: String)
implicit def object2SpecialPerson (obj: Object): SpecialPerson = {
if (obj.getClass == classOf[Student]) { val stu = obj.asInstanceOf[Student]; new SpecialPerson(stu.name) }
else if (obj.getClass == classOf[Older]) { val older = obj.asInstanceOf[Older]; new SpecialPerson(older.name) }
else Nil
}
var ticketNumber = 0
def buySpecialTicket(p: SpecialPerson) = {
ticketNumber += 1
"T-" + ticketNumber
}
scala> var stu =new Student("qinkaixin")
stu: Student = Student@2f6bbeb0
scala> buySpecialTicket(stu)
res0: String = T-1
複製程式碼
1.2 使用隱式轉換加強現有型別
隱式轉換非常強大的一個功能,就是可以在不知不覺中加強現有型別的功能。也就是說,可以為某個類定義一個加強版的類,並定義互相之間的隱式轉換,從而讓源類在使用加強版的方法時,由Scala自動進行隱式轉換為加強類,然後再呼叫該方法。
案例:超人變身
詳解:當呼叫不屬於Man的方法時,指直接呼叫隱式轉換函式man2superman,並呼叫emitLaser方法
class Man(val name: String)
class Superman(val name: String) {
def emitLaser = println("emit a laster!")
}
implicit def man2superman(man: Man): Superman = new Superman(man.name)
val leo = new Man("leo")
leo.emitLaser
複製程式碼
1.3 隱式引數
所謂的隱式引數,指的是在函式或者方法中,定義一個用implicit修飾的引數,此時Scala會嘗試找到一個指定型別的,用implicit修飾的物件,即隱式值,並注入引數。
Scala會在兩個範圍內查詢:
-
一種是當前作用域內可見的val或var定義的隱式變數;
-
一種是隱式引數型別的伴生物件內的隱式值
案例:考試簽到 詳解:簽到筆作為隱式引數,注入到函式中,從而可以使用隱式引數物件的屬性。 class SignPen { def write(content: String) = println(content) } implicit val signPen = new SignPen def signForExam(name: String) (implicit signPen: SignPen) { signPen.write(name + " come to exam in time.") } 複製程式碼
2 Java 手寫執行緒池
2.1 PThread 實現
public class PThread extends Thread
{
private ThreadPool pool;
private Runnable target;
private boolean isShutDown = false;
private boolean isIdle = false;
public PThread(Runnable target, String name, ThreadPool pool)
{
super(name);
this.pool = pool;
this.target = target;
}
public Runnable getTarget()
{
return target;
}
public boolean isIdle()
{
return isIdle;
}
public void run()
{
while (!isShutDown)
{
isIdle = false;
if (target != null)
{
target.run();
}
isIdle = true;
try
{
pool.repool(this);
synchronized (this)
{
wait();
}
}
catch (InterruptedException ie)
{
}
isIdle = false;
}
}
public synchronized void setTarget(java.lang.Runnable newTarget)
{
target = newTarget;
notifyAll();
}
public synchronized void shutDown()
{
isShutDown = true;
notifyAll();
}
}
複製程式碼
2.2 ThreadPool 實現
import java.util.List;
import java.util.Vector;
public class ThreadPool
{
private static ThreadPool instance = null;
private List<PThread> idleThreads;
private int threadCounter;
private boolean isShutDown = false;
private ThreadPool()
{
this.idleThreads = new Vector(5);
threadCounter = 0;
}
public int getCreatedThreadsCount() {
return threadCounter;
}
public synchronized static ThreadPool getInstance() {
if (instance == null)
instance = new ThreadPool();
return instance;
}
protected synchronized void repool(PThread repoolingThread)
{
if (!isShutDown)
{
idleThreads.add(repoolingThread);
}
else
{
repoolingThread.shutDown();
}
}
public synchronized void shutdown()
{
isShutDown = true;
for (int threadIndex = 0; threadIndex < idleThreads.size(); threadIndex++)
{
PThread idleThread = (PThread) idleThreads.get(threadIndex);
idleThread.shutDown();
}
}
public synchronized void start(Runnable target)
{
PThread thread = null;
if (idleThreads.size() > 0)
{
int lastIndex = idleThreads.size() - 1;
thread = (PThread) idleThreads.get(lastIndex);
idleThreads.remove(lastIndex);
thread.setTarget(target);
}
else
{
threadCounter++;
thread = new PThread(target, "PThread #" + threadCounter, this);
thread.start();
}
}
}
複製程式碼
2.3 ThreadPool 測試
public void testThreadPool() throws InterruptedException {
long starttime=System.currentTimeMillis();
for(int i=0;i<1000;i++){
ThreadPool.getInstance().start(new MyThread("testThreadPool"+Integer.toString(i)));
}
long endtime=System.currentTimeMillis();
System.out.println("testThreadPool"+": "+(endtime-starttime));
System.out.println("getCreatedThreadsCount:"+ThreadPool.getInstance().getCreatedThreadsCount());
Thread.sleep(1000);
}
複製程式碼