創建線程:
package thread;
public class MutiThreadDemo {
public static void main(String[] args) {
SonOfThread s1= new SonOfThread("zhangsan");
SonOfThread s2= new SonOfThread("lisi");
Thread t1 = new Thread(new RunnableImpl());
Thread t2 = new Thread(new RunnableImpl());
/*
* 不論哪種方法都是通過start來啓動線程的,啓動線程後,JVM會自動調用run方法
* 直接.run()不是啓動線程,而是調用run方法。
*/
s1.start();
s2.start();
t1.start();
t2.start();
for(int j=0;j<10;j++){
for(int i=0;i<1000000;i++){}
System.out.println(Thread.currentThread().getName()+"....."+j);
}
}
}
class SonOfThread extends Thread{
/*
* 自定義線程類繼承Thread,重寫run方法,使用的是Thread類的空參構造方法
*/
private String name;
public SonOfThread(String name) {
super();
this.name = name;
}
@Override
public void run() {
for(int j=0;j<10;j++){
for(int i=0;i<1000000;i++){}
System.out.println(Thread.currentThread().getName()+"....."+j);
}
}
}
class RunnableImpl implements Runnable{
/*
* 定義一個類實現Runnable接口,重寫run方法,使用的是Thread類的Thread(Runnable target)
* 構造方法,推薦使用實現接口的創建方式
* 好處是:1、 可將線程任務封裝成對象2、避免java單繼承的侷限性
*/
public void run() {
for(int j=0;j<10;j++){
for(int i=0;i<1000000;i++){}
System.out.println(Thread.currentThread().getName()+"....."+j);
}
}
}
線程安全的單例模式:
package thread;
/*
* 線程安全的懶漢式單例模式,既然爲單例就要保證構造方法私有化,提供一
* 個公共的方法可以獲取到單例。static說明:既然是懶漢單例模式,那麼在
* 該單例還未實例化之前,該類是沒有對象的,所以獲取對象的getInstance
* 方法不能通過具體的對象來調用,那麼就只能定義爲static,通過類來調用,
* 而單例的實例化是在getInstance方法中完成的,所以s也應該定義爲static。
* 實例化之前加一個判斷是爲了保證單例,外層加同步鎖是瞭解決線程安全爲題,
* 防止出現多個實例,而鎖的外層再加一個判斷是爲了解決效率問題,這樣線程
* 執行的時候就不必每次都判斷鎖,另外一個:即使是有了外層的判斷,內層的
* 也不可以省略,因爲有可能一個線程執行到第一個判斷條件是判斷s=null爲真,
* 還未拿到鎖就失去了cpu的執行權而停止。這時第二個線程也判斷s=null爲真,
* 那麼無論這兩個線程誰先拿到鎖,如果沒有內層的判斷,最終都會實例化出兩個
* 對象。
*/
public class Singleton {
private static Singleton s = null;
private Singleton(){}
public static Singleton getInstance(){
if(s==null){
synchronized(Singleton.class){
if(s==null){
s = new Singleton();
}
}
}
return s;
}
}