百战程序员10-多线程

  参考大佬的博客-链接

  1、程序、进程、线程的区别是什么? 举个现实的例子说明。(网上查资料,跟老师的
不一样)

  程序只是一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体。而进程则不同,它是程序在某个数据集上的执行。进程是一个动态的实体,它有自己的生命周期。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消。反映了一个程序在一定的数据集上运行的全部动态过程。

   进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。

  线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

  两者的区别:

  • 进程是资源分配的最小单位,线程是程序执行的最小单位。

  • 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

  • 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。

  • 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

  2、【上机】Java中通过哪些方式创建多线程类? 分别使用代码说明。并调用之。

     1、继承Thread类创建线程

    2、实现Runnable接口创建线程

    3、实现Callable接口通过FutureTask包装器来创建Thread线程

    4、使用ExecutorService、Callable、Future实现有返回结果的线程

  3、Thread类有没有实现Runnable接口?

     没有

  4、当调用一个线程对象的start方法后,线程马上进入运行状态吗?

     线程对象调用start()方法后,进入 就绪态

  5、下面的代码,实际上有几个线程在运行:

public static void main(String[] argc) throws Exception {

              Runnable r = new Thread6();

              Thread t = new Thread(r, "Name test");

              t.start();

}

 

  6、说说:sleep、yield、join方法的区别

    网页链接

  7、为什么不推荐使用stop和destroy方法来结束线程的运行?

       

    从SUN的官方文档可以得知,调用Thread.stop()方法是不安全的,这是因为当调用  Thread.stop()方法时,会发生下面两件事:

    1. 即刻抛出ThreadDeath异常,在线程的run()方法内,任何一点都有可能抛出ThreadDeath   Error,包括在catch或finally语句中。

    2. 释放该线程所持有的所有的锁

    

    

  • 1.设置退出标志,使线程正常退出,也就是当run()方法完成后线程终止

  • 2.使用interrupt()方法中断线程

  • 3.使用stop方法强行终止线程(不推荐使用,Thread.stop, Thread.suspend, Thread.resume 和Runtime.runFinalizersOnExit 这些终止线程运行的方法已经被废弃,使用它们是极端不安全的!)

    

  8、【上机】写个代码说明,终止线程的典型方式

 

  9、A线程的优先级是10,B线程的优先级是1,那么当进行调度时一定会调用A吗?

       

    线程的优先级可以通过setPriority(int newPriority)的方法进行设置

         线程一共有三个优先级,分别是:
    最低优先级(1) 中等优先级(5)最高优先级(10),main方法就是中等优先级线程。 A:线程的优先级是可以更改也可以获取,但是有一点,即使设置为最高 优先级也不一定先执行,只是它优先执行的几率比较高。 B:线程的优先级是在创建时进行设置,通过setPriority()方法设置   C:正在执行的线程是不允许重新设置线程优先级的。

  10、【上机】模仿老师课堂例子,完成账户取钱的模拟操作代码

   

  11、synchronized修饰在方法前是什么意思?

     synchronized是用来完成多线程条件下同步工作的

    synchronized 修饰方法时锁定的是调用该方法的对象。它并不能使调用该方法的多个对象在执行顺序上互斥。

  12、synchronized修饰的语句块,如下面的代码。是表示该代码块运行时必须获得
         account对象的锁。如果没有获得,会有什么情况发生?

synchronized (account) {

                     if(account.money-drawingNum<0){

                            return;

                     }

}

   转账收不到钱。转了不扣钱

  13、【上机】死锁是怎么造成的?用文字表达。再写一个代码示例。

     死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

  14、使用Timer和TimerTask实现定时执行,定时在每天下午17:00执行。

     网页链接

  15、wait方法被调用时,所在线程是否会释放所持有的锁资源? sleep方法呢?

     wait:释放CPU,释放锁。

     sleep:释放CPU,不释放锁。

  16、wait、notify、notifyAll是在Object类中定义的方法吗,作用分别是什么?

     wait()、notify()、notifyAll()不属于Thread类,而是属于Object类,也就是说每个对象都有wait()、notify()、notifyAll()的功能。因为每个对象都有锁,锁是每个对象的基础。而wait()、notify()、notifyAll()都是跟锁有关的方法。

    

    作用:

        wait():导致当前线程等待,进入阻塞状态,直到其他线程调用此对象的notify()方法或者notifyAll方法。当前线程必须拥有此对象监视器(对象锁)。该线程释放对此监视器的所有权并等待,直到其他线程通过调用notify方法,或者notifyAll方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。

        notify():唤醒在此对象监视器(对象锁)上等待单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。此方法只应由作为此对象监视器的所有者的线程来调用。

“当前线程必须拥有此对象监视器(对象锁)”与“此方法只应由作为此对象监视器的所有者的线程来调用”说明——wait方法和notify方法必须在同步代码块内执行,即synchronized(obj之内)。

        notifyAll():唤醒在此对象监视器(对象锁)上等待的所有线程。

  17、notify是唤醒所在对象wait pool中的第一个线程吗?

     

    不是。

        调用notify()方法导致解除阻塞的线程是从因调用该对象的wait()方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择

  18、【上机】使用线程通信实现生产者-消费者问题。

 

猜你喜欢

转载自www.cnblogs.com/lshaoyu/p/10453335.html
今日推荐