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的调度策略
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章