java線程的三種創建方式對比

1. 繼承Thread
public class Thread2 extends Thread{
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
	}
	
	public static void main(String[] args) {
		new Thread2().start();
	}
}

2. 實現Runnable接口
public class Thread3 implements Runnable{
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
	}
	public static void main(String[] args) {
		new Thread(new Thread3()).start();
	}
}
其中Runnable裏面只有一個run方法
public
interface Runnable {
    public abstract void run();
}


3. 實現Callable接口,與第二種方法沒有什麼區別
     call方法作爲執行主體,比run方法更靈活,可以有返回值,拋出異常
public class thread3 implements Callable<String>{
	
	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
	
	public static void main(String[] args) {
		thread3 t3 = new thread3();
		FutureTask<String> futureTask = new FutureTask<String>(t3);
		new Thread(futureTask).start();
	}
}

4. 下面看一下Thread類源碼:
public Thread() {
	init(null, null, "Thread-" + nextThreadNum(), 0);
    }

public Thread() {
	init(null, null, "Thread-" + nextThreadNum(), 0);
    }

public Thread(ThreadGroup group, Runnable target) {
	init(group, target, "Thread-" + nextThreadNum(), 0);
    }
Thread的初始化函數最終都會調用下面的init方法
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
	Thread parent = currentThread();
	SecurityManager security = System.getSecurityManager();
	if (g == null) {
	    /* Determine if it's an applet or not */
	    
	    /* If there is a security manager, ask the security manager
	       what to do. */
	    if (security != null) {
		g = security.getThreadGroup();
	    }

	    /* If the security doesn't have a strong opinion of the matter
	       use the parent thread group. */
	    if (g == null) {
		g = parent.getThreadGroup();
	    }
	}

	/* checkAccess regardless of whether or not threadgroup is
           explicitly passed in. */
	g.checkAccess();

	/*
	 * Do we have the required permissions?
	 */
	if (security != null) {
	    if (isCCLOverridden(getClass())) {
	        security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
	    }
	}


        g.addUnstarted();

	this.group = g;
	this.daemon = parent.isDaemon();
	this.priority = parent.getPriority();
	this.name = name.toCharArray();
	if (security == null || isCCLOverridden(parent.getClass()))
	    this.contextClassLoader = parent.getContextClassLoader();
	else
	    this.contextClassLoader = parent.contextClassLoader;
	this.inheritedAccessControlContext = AccessController.getContext();
	this.target = target;
	setPriority(priority);
        if (parent.inheritableThreadLocals != null)
	    this.inheritableThreadLocals =
		ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }

  1.  從上面代碼看出thread的parent取得是當前線程,也就是創建該線程的線程
2. 線程的ThreadGroup默認是父線程的
 public ThreadGroup getThreadGroup() {
	return Thread.currentThread().getThreadGroup();
    }
3. 其他的諸如daemon 、priority都與父線程保持一致,另外尤其說一下name屬性
public Thread() {
	init(null, null, "Thread-" + nextThreadNum(), 0);
    }
/* For autonumbering anonymous threads. */
    private static int threadInitNumber;
    private static synchronized int nextThreadNum() {
	return threadInitNumber++;
    }


所以如果創建線程時沒有顯示指定線程名,迷人的線程名就會是Thread1,Thread3......

4. Thread.GetCurrentThread.getName
5. 線程的5種狀態
     準備 就緒 阻塞 執行 結束
6. 線程優先級
優先級高的線程被調度的概率大,也不是一定優先級高的線程會先於優先級低的線程調用,具體看JVM的調度策略
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章