【Java并发学习】之详解线程的点滴(1)

2017-11-12  本文已影响25人  颜洛滨

【Java并发学习】之详解线程的点滴(1)

前言

在前面的几个小节中,我们粗略地学习了线程的基本概念,定义任务的方式,并且通过Java中的多线程API来驱动对应的任务,然后学习了线程的互斥与同步关系,线程之间进行资源共享后的同步操作等等一些简单的内容,可以说,线程中的主要内容我们已经掌握了,然而,也仅仅只是简单内容,很多比较细节、复杂的东西在之前我们刻意避开了,接下来的几个小节中,我们就来具体地学习线程的各个细节内容

线程的属性

线程有许多的属性,比如线程的ID、名字、优先级、状态等,接下来我们就来具体学习这些属性

线程的ID

每个线程都有对应的独一无二的ID,这些ID是由JVM在运行的时候为线程设置的,用于区分不同的线程,并且不对外提供设置线程ID的接口,也就是说,在Java中,我们仅能够获取多线程的ID,而不能设置线程的ID,访问代码如下


    class DetailTask implements Runnable{

        @Override
        public void run() {
            System.out.println("Details : " + Thread.currentThread().getId());
            // 其中Thread.currentThread()用于获取当前执行的线程
            // 通过thread.getId()则可以获取对应的线程的ID
        }
    }

线程的名字

在线程比较多的情况下,我们会倾向于根据执行不同任务的不同线程来为其设置名字,方便在日志以及其他场景中使用到,设置以及获取线程的名字操作具体如下


    class DetailTask implements Runnable{

        private static int cnt = 0;
        // 注意这里的代码是非线程安全的
        @Override
        public void run() {
            Thread.currentThread().setName("Thread " + cnt++); // 设置线程名字
            System.out.println("Details : " + Thread.currentThread().getName()); // 获取线程的名字
        }
    }

线程优先级

优先级是一个比较有价值的概念,在Java中,线程之间的调度采用的是基于时间片的轮转调度方式,其中在线程进行切换,重新调度时,调度的主要依据就是优先级,通常来说,优先级比较高的线程,被调度的可能性会比较大,也就是说,在单位时间内,优先级高的线程被调度的次数会大于优先级低的线程

不过,在设置线程的优先级的时候,需要注意一下几点


    for (int i = 0; i < 10; i++){
        Thread thread = new Thread(task);
        System.out.println("Priority " + thread.getPriority());
        if (i % 2 == 0){
            thread.setPriority(Thread.MIN_PRIORITY); // 设置优先级为最低
        }else {
            thread.setPriority(Thread.MAX_PRIORITY); // 设置优先级为最高
        }
        thread.start();
    }

线程的状态

通常来讲,线程的数量是多于CPU的数量,这也就意味着,为了保证每个线程都能得到执行,在特定时刻,总会有线程处于非运行状态,当然,Java中线程的状态不止这两种,具体如下

关于这几个状态的详细介绍,可以参考JDK源码中的注释


    /* A thread can be in only one state at a given point in time.
     * These states are virtual machine states which do not reflect
     * any operating system thread states.
     *
     * @since   1.5
     * @see #getState
     */
    public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

守护线程

上面我们主要学习了线程的几个属性,ID、名字、优先级、状态等,接下来我们来学习一个新的概念,守护线程

守护线程是一类特殊的线程,主要的特点如下

基于守护线程的特点,在使用的时候需要注意,不能在守护线程中做一些逻辑比较复杂的操作,不能做一些比较重要的操作

一个典型的使用守护线程的例子就是JVM中的垃圾回收器

    
    public static void main(String[] args) {
        Thread daemonTask = new Thread(new DaemonTask());
        daemonTask.setDaemon(true);// 设置为守护线程,这里同样需要注意,必须在线程启动之前进行设置
        daemonTask.start();
    }

    class DaemonTask implements Runnable{
        @Override
        public void run() {
            while (true){
                System.out.println("I'm Daemon thread");
            }
        }
    }

总结

本小计我们主要学习了线程的相关属性,包括了ID、名字、优先级、状态,以及守护线程的概念和设置守护线程的方法,线程中的异常处理,接下来我们将学习线程的中断以及线程的异常处理等等的内容

上一篇下一篇

猜你喜欢

热点阅读