0
点赞
收藏
分享

微信扫一扫

Java 线程的创建方式和启动方式有什么区别?为什么?怎么样合理封装线程?


因为疫情与工作等关系,深海已经三个月没有更新博客了,这次深海给大家分享一下线程的小知识吧

线程的创建方式有哪些区别?为什么?

1.new Thread().start();

2.new Thread(new MyThreadRunnable()).start();

private class MyThreadRunnable implements Runnable{
@Override
public void run() {

}
}

怎么样是不是很相似?  没错,某种意义上讲没有什么区别,无非多一个Runnable参数.来咱们看一下源码:

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

这个是Thread的有参构造方法,里面调用了init方法.如下

private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
Thread parent = currentThread();
if (g == null) {
g = parent.getThreadGroup();
}

g.addUnstarted();
this.group = g;

this.target = target;
this.priority = parent.getPriority();
this.daemon = parent.isDaemon();
setName(name);

init2(parent);

/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
tid = nextThreadID();
}

您看这一句this.target = target;     可以看出替换了Thread中的Runnable变量.

这个变量被换了有什么用呢?  来我找到了,咱们继续往下看:

@Override
public void run() {
if (target != null) {
target.run();
}
}

看到了吧,如果你创建的Thread传Runnable参数了,那么执行Thread中的Run方法时,会执行你传的Runnable参数中的Run方法.

假如,用第一种方式,不传Runnable呢?源码如下:

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

第二个参数 (Runnable参数)传了空.

创建方式总结:

1.在封装的角度考虑,如果你设计的线程类继承了Thread,那么该类就无法再继承其他的类.

但是如果你实现了Runnable接口,然后进行封装的话,不会影响该类的继承扩展空间.

2.如果你实现了Runnable接口进行封装,那么你可以把改封装类对象传入多个线程中,

这样就实现了多个线程执行同样的逻辑资源.

线程的启动方式?

new MyThread().start();?

new MyThread().run();?

以上两种,是吗?不是!

线程的启动方式只有一种,就是start()方法!

而run()方法只是在当前线程运行方法中的逻辑资源罢了.并且我在上面有贴源码

来看一下start方法的源码:

public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
// Android-changed: throw if 'started' is true
if (threadStatus != 0 || started)
throw new IllegalThreadStateException();

/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);

started = false;
try {
nativeCreate(this, stackSize, daemon);
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}

只有start方法中调用了 nativeCreate(this, stackSize, daemon);  创建了线程.

结尾:相信您读到这里,应该明白如何去封装线程了吧,深海先去忙了,希望您点赞评论加关注哦!

举报

相关推荐

0 条评论