java多线程编程基础

1.进程和线程的区别是什么?
进程是执行着的应用程序,如手机上的一个应用。而线程是在进程中执行的一个任务,他可以共享进程中的资源。线程可以被称为轻量级进程,它在进程中进行创建和销毁线程相比于进程的创建和销毁需要较少的资源和花销。

一个进程虽然包括多个线程,但是这些线程是共同享有进程占有的资源和地址空间的。进程是操作系统进行资源分配的基本单位,而线程是操作系统进行调度的基本单位。

2.创建线程有几种不同的方式?
@see http://blog.csdn.net/sinat_34814635/article/details/78959162

3.线程的几种状态?

线程一共有6种状态。

源码如下:

 /**
     * A thread state.  A thread can be in one of the following states:
     * <ul>
     * <li>{@link #NEW}<br>
     *     A thread that has not yet started is in this state.
     *     </li>
     * <li>{@link #RUNNABLE}<br>
     *     A thread executing in the Java virtual machine is in this state.
     *     </li>
     * <li>{@link #BLOCKED}<br>
     *     A thread that is blocked waiting for a monitor lock
     *     is in this state.
     *     </li>
     * <li>{@link #WAITING}<br>
     *     A thread that is waiting indefinitely for another thread to
     *     perform a particular action is in this state.
     *     </li>
     * <li>{@link #TIMED_WAITING}<br>
     *     A thread that is waiting for another thread to perform an action
     *     for up to a specified waiting time is in this state.
     *     </li>
     * <li>{@link #TERMINATED}<br>
     *     A thread that has exited is in this state.
     *     </li>
     * </ul>
     *
     * <p>
     * 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;
    }

新创建(New):线程刚刚创建,即处于初始状态,此状态线程还不能够运行。

可运行(Runnable): 在调用thread.start()方法后,就变成了Runnable状态。Runnable状态其实包含了可运行和正在运行的两种状态

被阻塞状态(Blocked):等待获取锁或未获取到锁,线程无法得到执行。

等待(Waiting): 线程等待另一个线程通知调度器一个条件时,该线程处于waiting状态。如调用object.wait()或者thread.join()方法后。

计时等待(timed waiting):设置了等待参数。

被终止(TERMINATED):线程完成了run()方法的执行而正常终止或者执行run()方法过程中抛出异常。

这里写图片描述

备注:可以调用thread.getState()来查看线程的状态。

为了便于理解,在将各个状态进行如下拆分,其中的关系参考如图:

这里写图片描述

备注:调用join或者sleep方法后,线程是处于waiting或timed waiting状态。
状态解释:

初始状态:线程刚刚创建,即处于初始状态,此状态线程还不能够运行。

可运行状态:线程准备运行,不一定立马就能开始执行。要被调度中心选中之后才能运行。

运行中(Running):进程正在执行线程的代码。即在执行run()方法.

生命周期:
当我们在Java程序中新建一个线程时,它的状态是New。当我们调用线程的start()方法时,状态被改变为Runnable。线程调度器会为Runnable线程池中的线程分配CPU时间并且讲它们的状态改变为Running。

可参看下图理解
在这里插入图片描述
@see 线程生命周期https://www.journaldev.com/1044/thread-life-cycle-in-java-thread-states-in-java

什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?

线程调度器:线程调度器是一个操作系统服务,它负责为Runnable状态的线程分配CPU时间。一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现。线程调度并不受到Java虚拟机控制,所以由应用程序来控制它是更好的选择(也就是说不要让你的程序依赖于线程的优先级)。
时间分片:时间分片是指将可用的CPU时间分配给可用的Runnable线程的过程。

线程中常用到的方法:
thread类:
1、public static void yield()
暂停当前正在执行的线程对象,并执行其他线程(也有可能会执行到自己这个线程)

2.public final void join()
等待该线程终止。
1)join是Thread类的一个方法,启动线程后直接调用,即join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。
2)为什么要用join()方法

  • 在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。

3.public static void sleep(long millis) throws InterruptedException

在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。
注意:sleep方法不好释放自己的同步锁,这是和object.wait()方法的最大区别。

object类:
1)public final void wait()
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
注意:wait方法会释放自己的同步锁,也就是其他线程可以进入被锁住的方法。
2)public final void notify()和public final void notifyAll()

notify():唤醒在此对象监视器上等待的单个线程
notifyAll():唤醒在此对象监视器上等待的所有线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争,即具体会执行哪一个线程是不确定。
执行完notify()或者notifyAll()方法后,该线程如果拿到了同步锁就会变成可运行状态(Runnable)。

线程之间的通信也主要是通过wait()\notify()\notifyAll()方法来完成的。

4.同步方法和同步代码块的区别是什么?

5.多线程编程的特点
1.优点

1.在多线程程序中,多个线程被并发的执行以提高程序的效率,CPU不会因为某个线程需要等待资源而进入空闲状态。如果是单线程执行遇到一些io操作会进行等待状态。

2.可能会存在的问题

1.并发问题

2.资源占有问题

可能消耗CPU的资源

6.用户线程和守护线程有什么区别?
1.当我们在Java程序中创建一个线程,它就被称为用户线程。
2.一个守护线程是在后台执行并且不会阻止JVM终止的线程。
当没有用户线程在运行的时候,JVM关闭程序并且退出。一个守护线程创建的子线程依然是守护线程。

7.在多线程中,什么是上下文切换(context-switching)?
上下文切换是存储和恢复CPU状态的过程,它使得线程执行能够从中断点恢复执行。上下文切换是多任务操作系统和多线程环境的基本特征。

参考资料:
1.《core java》
2.https://www.cnblogs.com/dolphin0520/p/3932934.html

猜你喜欢

转载自blog.csdn.net/sinat_34814635/article/details/79508688