Java 多线程Thread源码学习


前言

进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)

线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)

一、多线程创建及使用

代码如下:

//创建新线程需实例化Thread,调用start方法
public class ThreadTest extends Thread{
    public static void main(String[] args) throws InterruptedException{
        Thread t = new ThreadTest();
        t.start();
        int i =1;
        while (i<10){
            System.out.println(Thread.currentThread().getName()+":打印"+i);
            i++;
        }
    }
    @Override
    public synchronized void run() {
        int i = 1;
        while (i<10){
            System.out.println(this.getName()+":打印"+i);
            i++;
        }
    }
}

运行结果

main:打印1
main:打印2
Thread-0:打印1
Thread-0:打印2
Thread-0:打印3
Thread-0:打印4
Thread-0:打印5
Thread-0:打印6
Thread-0:打印7
Thread-0:打印8
Thread-0:打印9
main:打印3
main:打印4
main:打印5
main:打印6
main:打印7
main:打印8
main:打印9

源码阅读

1、构造方法

//Thread构造方法调用init()完成线程属性初始化,继承Thread类的一般调用此构造方法
public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }
//实现Runnable接口的,一般调用此构造方法
public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

2、init()方法

//继续调用重载的init()方法
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }
//ThreadGroup线程组,默认为父线程组,target线程运行的内容,name线程名称,stackSize线程栈大小,acc访问控制,inheritThreadLocals判断是否可访问父线程的ThreadLocal
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
		//设置线程名称
        this.name = name;
		//当前运行的线程即该实例父线程
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            /* 判断是否为小应用程序 */
            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }
            /* 线程组为父线程的线程组. */
            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);
            }
        }
		//线程组中未启动线程数量+1
        g.addUnstarted();
		//绑定线程组
        this.group = g;
        //设置是否为守护线程
        this.daemon = parent.isDaemon();
        //设置权重
        this.priority = parent.getPriority();
        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);
        //可继承的ThreadLocal
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* 设置线程id */
        tid = nextThreadID();
    }

3、线程启动start()方法

public synchronized void start() {
    	//threadStatus状态不为0时报错
        if (threadStatus != 0)
            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);
		//标志
        boolean started = false;
        try {
        	//本地方法,虚拟机调用
            start0();
            //未保存,设置成功标志
            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 */
            }
        }
    }

总结

以上就是要讲的内容,本文仅仅简单阅读了Thread类源码,如有错误请指出,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值