秦凱新技術社區推出的《Coding技術進階實戰》系列即將上線,包含語言類精深的用法和技巧,涵蓋 python,Java,Scala,Tensorflow等主流大數據和深度學習技術基礎,敬請期待。爲何我會寫這樣一個系列,來源於被一位容器雲專家問到如何實現一個線程池時,讓我頓感之前研究的Java併發控制相關的理論以及多線程併發設計模式忘得九霄雲外,鑑於此,氣憤難平,決定展現我的編程魅力。java
版權聲明:本套技術專欄是做者(秦凱新)平時工做的總結和昇華,經過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和集羣環境容量規劃等內容,請持續關注本套博客。QQ郵箱地址:1120746959@qq.com,若有任何技術交流,可隨時聯繫。python
要實現隱式轉換,只要程序可見的範圍內定義隱式轉換函數便可。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
複製代碼
隱式轉換很是強大的一個功能,就是能夠在不知不覺中增強現有類型的功能。也就是說,能夠爲某個類定義一個增強版的類,並定義互相之間的隱式轉換,從而讓源類在使用增強版的方法時,由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
複製代碼
所謂的隱式參數,指的是在函數或者方法中,定義一個用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.")
}
複製代碼
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();
}
}
複製代碼
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();
}
}
}
複製代碼
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);
}
複製代碼