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);  创建了线程.

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

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值