美文网首页云计算
多线程相关问题(一)

多线程相关问题(一)

作者: NealLemon | 来源:发表于2019-02-09 09:01 被阅读142次

    由于近期在做知识储备,在做很多的复习,把之前看过的内容重温一遍真的像重新看一遍一样,真的是一入JAVA深似海。

    概念相关问题

    1.线程和进程有什么区别?

    线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

    2.线程的状态有哪些?

    Java线程状态转换.jpg

    相关方法问题

    1.start和run方法的区别?

    在这里我们先写一段代码来实际感受一下这两个方法的区别。

    /**
     * 针对run()和 start()区别的测试类
     */
    public class ThreadTest {
    
        /**
         * 单纯打印执行内容以及当前线程的线程名
         */
        private static void doTest(String name) {
            System.out.println("使用"+ name + "方法调用doTest()");
            System.out.println("Current Thread is : " + Thread.currentThread().getName());
        }
    
        public static void main(String[] args) {
            Thread startThread = new Thread() {
                @Override
                public void run() {
                    doTest("start()");
                }
            };
    
            Thread runThread = new Thread() {
                @Override
                public void run() {
                    doTest("start()");
                }
            };
            startThread.start();
    
            runThread.run();
        }
    
    }
    

    执行结果


    结果.png
    具体分析

    我们先来看一下java.lang.Thread#start方法的源码

    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 */
            }
        }
    }
    

    上述源码中 实际启动的就是 start0();这个方法。我们查看源码可以看到 这个方法也是一个native方法。

    private native void start0();
    

    我们接着查看一下native中的相关源码。这里就直接给出源码以及重点,具体怎么查询的可以自行百度。

    start.png start1.png

    由上述的虚拟机源码,我们可以就可以看明白刚刚我们写的demo中的结果的原因了。

    总结

    图解:

    总结.png
    • 调用start()时,会创建一个新的子进程并启动
    • 调用run()时,支持thread的普通方法调用,依旧在主线程中调用。

    2.sleep()和wait()的区别?

    • sleep()是Thread类的方法,wait()是Object类中定义的方法。
    • sleep()方法可以在任何地方使用,wait()只能在synchronized方法或代码快中使用
    • Thread.sleep 只会让出cpu,不会导致锁行为的改变
    • Object.wait不仅让出cpu,还会释放已经占有的同步锁资源

    3.notify() 和 notifyAll()的区别?

    首先需要了解一下两个概念。

    锁池
    锁池.png
    等待池
    等待池.png
    • notifyAll()让所有处于等待池的线程全部进入锁池去竞争锁的机会
    • notify() 会随机选择一个线程进入锁池去竞争。

    4.yield和join的区别?

    • 一个调用yield()方法的线程告诉虚拟机它乐意让其他线程占用自己的位置。这表明该线程没有在做一些紧急的事情。注意,这仅是一个暗示,并不能保证不会产生任何影响。
    • 得一个线程在另一个线程结束后再执行。如果join()方法在一个线程实例上调用,当前运行着的线程将阻塞直到这个线程实例完成了执行。

    5.调用Interrupt()函数

    • 如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。
    • 如果线程处于正常活动状态,那么会将该线程的中断标志设置为true,被设置中断标志的线程将继续正常运行。不受影响。
    • 需要被调用的线程配合中断
      • 在正在运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程。

    相关文章

      网友评论

        本文标题:多线程相关问题(一)

        本文链接:https://www.haomeiwen.com/subject/fztasqtx.html