关于线程一些概念和理解

1.什么是线程,进程:

    →:线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程的实际运作单位,

    例子:计算机的核心是cpu,他承担了所有的计算任务,时刻在运行,而进程就好比它的车间(可以有单个,也可以是多个,根据cpu的核数决定,

              这里主要说的就是单核的情况只能同时有一个车间工作),当一个车间工作的时候,其他的车间就不能够工作了。但是一个车间里面可以有好多个工人(线程),

              车间里面的空间是工人们所共享的,当然也有例外,有些情况就不允许大家同时访问某些空间,比如厕所...解决方案:互斥锁,还有一些资源允许同时访问,但是要判断访问的人数和可容纳人数的关系,(信号量                 机制)。

    自己的例子:我们写的代码中在执行一个操作的同时需要进行另外一些操作,Ajax,异步请求!单独发的Ajax请求就是一个线程,它也属于进程(我们编写的代码)的一部分,而且也可以使用进程的资源。2018-11-17

2.如何创建一个线程:

    →线程的分类:用户级线程和内核级线程

        用户及线程:线程归进程管理,cpu并不知道线程的存在,在分配资源的时候是按照进程分配的,单核多核对于它并没有什么区别

        内核级线程:线程归cpu管理,在分配资源的时候是按照线程数来分配资源,可以充分发挥多核的效率,但是每次线程的调用都是系统调用,代价大

        组合方式:线程创建完全在用户空间中完成,线程的调度和同步也是在应用程序中进行,一个应用程序中的多个用户级线程被映射到内核级线程中(通过线程池)

    →创建线程

        继承thread类:

            使用方法:重写run()方法,通过new 对象 .start()来创建一个新的线程

        实现runable接口:内部只有一个抽象方法run()

       

When an object implementing interface <code>Runnable</code> is used

* to create a thread, starting the thread causes the object's

* <code>run</code> method to be called in that separately executing

* thread.

---public abstract void run();

            使用方法:重写run()方法,new thread(将类作为参数传入)调用构造方法

public Thread(Runnable target) {

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

}

作为比较看一下无参构造:

public Thread() {

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

}

两者的初始化数据基本一致,只有runable参数target不同,这个参数的作用也无非就是this.target = target;对属性进行初始化。

init()方法:对thread中的一些属性进行初始化。

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) {

        /* 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();

    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 (inheritThreadLocals && 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();

}

start()方法:此处涉及线程的五种状态:创建,就绪,运行,阻塞,死亡

    →创建:生成线程对象还没有调用start()方法

    →就绪:调用start()方法,还没有运行run()方法

    →运行:执行run()内部代码

    →阻塞:线程执行期间被暂停

    →死亡:run()结束或者调用stop()方法

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".

     */

    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类和实现runable()接口实质上是一样的,所需要的只不过是自己重写的run()方法。实现了接口也不过是将重写的run()方法单独提了出来,然后再作为thread的构造方法的参数,通过init()方法进行thread对象的初始化。然后我们来看一下具体的thread.start()都做了哪些工作:调用start()方法后,会创建一个线程,准备好各项准备工作之后,调用run()方法来执行操作,另一方面主线程直接运行start()后面的代码,若直接调用run()也可以实现代码功能,只不过那样是同步执行的,就是一个普通的方法调用。

        通过callable和future task创建:简单说一下吧:其实看了半天也没太懂~~~

            貌似就是实现callable接口,重写call()方法,  然后调用Executors.newCacheThreadPool().submit(new 创建的对象);---有返回值    可以用Future<t> .get();获取返回值

        通过线程池创建:首次要了解一下线程池的各个概念:corePoolSize,maximumPoolSize,keepAliveTime,workQueue,handler.

            →corePoolSize:

            →miaximumPoolSize;核心线程和非核心线程的总数

            →keepAliveTime:非核心线程可以保留的最大空闲时间

            →workQueue:

            →handler:

            线程池的执行流程:(使用者)提交任务→(线程者)核心线程数是否满→(不满)创建线程执行任务→(满)队列是否已满→(不满)将任务存储在队列中→(满)线程池是否已满→(不满)创建线程执行任务→(满)按照策略处理相应任务

            →拒绝策略: abortpolicy:不执行新的任务,直接抛出异常

                                 discardpolicy:不执行新的任务也不抛出异常

                                discardoldsetpolicy:将消息队列中的第一个任务替换为新任务

                                callerrunspolicy:直接调用execute来执行当前任务

 

            常见的线程池:

                        cachedThreadPool:可缓存线程,没有核心线程,非核心线程为无限大,使用过后保留一段时间后若没有再次被使用则被回收

                        FixedThreadPool:定长的线程池,核心线程数即为最大线程数,没有非核心线程

                        SingleThreadPool:只有一条线程

                        schedulethreadpool:周期性线程池,核心线程数固定,且非核心线程数无限,常用于处理周期性任务

一下午就搞了这两个概念0.0,还是一知半解的,总结一下,线程和进程的大致了解,创建线程的4中方式,主要是实现callable接口有点难理解,先记得使用过程好了,之后再慢慢的体会加深理解吧。--------2018/11/17

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值