JAVA多线程-线程初始化及参数

先看下Thread的构造函数

Thread类有多个构造方法,但是所有的构造方法都会调用init()方法

线程名称

初始化的时候可以传入线程名称,也可以通过setName(String name) 方法设置,

这方法是个同步方法,当线程为非初始化时调用此方法无效,初始化的线程threadStatus0,

public final synchronized void setName(String name) {

        checkAccess();

        this.name = name.toCharArray();

        if (threadStatus != 0) {

            setNativeName(name);

        }

 }

线程如果我们不命名则有默认的名字我们可以看下源码:默认的名字为:

public Thread() {

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

 }

Thread-随机数

也可以在初始化时传入线程的名称:

public Thread(String name)

public Thread(ThreadGroup group, String name)

public Thread(Runnable target, String name)

public Thread(ThreadGroup group, Runnable target, String name)

public Thread(ThreadGroup group, Runnable target, String name,

                  long stackSize)

以第一个方法为测试方法看下

代码:

    public static void main(String[] args) {

        new Thread(()->{

            System.out.println("Thread name=========" +Thread.currentThread().getName());

        }, "test").start();

    }

     结果:

Thread name=========test

父子线程

在初始化线程的时候,所有构造方法都会调用init()方法:

private void init(ThreadGroup g, Runnable target, String name,

                      long stackSize, AccessControlContext acc) {

        if (name == null) {

            throw new NullPointerException("name cannot be null");

        }



        Thread parent = currentThread();

        SecurityManager security = System.getSecurityManager();

        if (g == null) {

            if (security != null) {

                g = security.getThreadGroup();

            }

            if (g == null) {

                g = parent.getThreadGroup();

            }

        }

        g.checkAccess();

        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 =

                acc != null ? acc : 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();

    }

代码中有一段这样的代码:

Thread parent = currentThread();

currentThread()就是获取当前线程,在线程的生命周期中此时的线程是NEW状态,没有调用start()方法之前,这个只是一个Thread对象,所有currentThread()就是创建它的那个线程,比如main方法的线程:

一个线程肯定是由另外一个线程创建的,被创建的线程的父线程就是创建它的线程。

线程组

初始化Thread的时候有个ThreadGroup的参数也就是线程组的意思,说明该线程属于哪一个线程组,这是为了方面管理线程,如果我们不传的话默认是父类的线程组,看下源码:
     

 if (g == null) {

            if (security != null) {

                g = security.getThreadGroup();

            }

            if (g == null) {

                g = parent.getThreadGroup();

            }

        }

Runnable

Runnable其实是线程的执行体也就是执行方法的接口,负责执行逻辑单元

stackSize

   /*

     * The requested stack size for this thread, or 0 if the creator did

     * not specify a stack size.  It is up to the VM to do whatever it

     * likes with this number; some VMs will ignore it.

     */

private long stackSize;

也是就是当前线程的指定栈大小,如果线程的创建者不指定大小,那默认值就是0,对这个值如何进行操作取决于JVM,有些JVM会忽略掉这个参数,这个值可以通过JVM参数xss设置

stackSize实际上代表着栈内存,就是每个线程分配多少内存,内存越小那么可以启动的线程就越多,反之,一个JVM的内存大可以这么表示:堆内存 + 线程数量 * 栈内存。

守护线程

JAVA分为两种线程:用户线程和守护线程

用户线程就是我们平时创建的线程

守护线程是之一些后台线程当其他线程执行完毕后,守护线程也会消失,比如垃圾回收线程;

设置守护线程的方法是调用Thread的setDaemon,方法的注解如下

Marks this thread as either a {@linkplain #isDaemon daemon} thread

     * or a user thread. The Java Virtual Machine exits when the only

     * threads running are all daemon threads.

This method must be invoked before the thread is started.

标记一线程为用户线程或者守护线程,如果on为true则创建的是守护线程,当只有守护线程运行时JVM会退出,该方法必须在调用线程启动之前,如果线程正在执行调用此方法会抛出IllegalThreadStateException

 public final void setDaemon(boolean on) {

    checkAccess();

        if (isAlive()) {

            throw new IllegalThreadStateException();

        }

        daemon = on;

}

猜你喜欢

转载自blog.csdn.net/cgsyck/article/details/104843554
今日推荐