• 问题整理


    1、实现线程有哪几种方式
    继承Thread类
    实现Runnable接口,重写run()方法
    实现Callable接口,重写call()方法 ,返回Future对象结果
    线程池:ExecutorService 中submit(runnable/callable)返回一个Future,Future可用来获得任务的执行结果或者取消任务

    2、用Runnable还是Thread?
    Java不支持类的多重继承,但允许你调用多个接口,如果类要继承其他类,当然是用Runnable接口

    3、Thread 类中的start(:和 run(:方法有什么区别?
    start()方法被用来启动新创建的线程,而且start()内部调用了run()方法
    当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程

    4、线程池有什么作用
    提前创建好指定数量的线程放在池中,等需要使用的时候就从池中使用,减少临时创建线程从而提高效率
    同时频繁的创建和销毁线程会浪费大量的系统资源,增加并发编程的风险

    5、线程池的参数
    线程池的核心线程数
    线程池程最大线程数量
    线程活动保持时间:非核心线程闲置时的超时时长,超过这个时长,非核心线程就会被回收
    用于指定线程活动保持时间参数的时间单位(分 秒)
    任务队列:用于保存等待执行的任务的阻塞队列

    6、Executors线程池有哪几种, 各有什么区别
    newSingleThreadExecutor 创建一个单线程化的线程池,单线程串行执行所有任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
    newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
    newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

    7、ExecutorService 的submit()与execute()区别
    submit()参数可以Runnable 也可以是Callable 有Future返回值 ,可以通过Future.get()进行抛出异常的捕获
    execute()参数只有Runnable 没有返回值

    8、Runnable()与Callable()区别 (都通过start()启动线程)
    Callable接口方法是call(),Runnable接口方法是run();
    Callable的call方法可以通过Future.get()进行抛出异常 (Callable可以返回装载有计算结果的Future对象 ,Callable的 call()方法可以返回值和抛出异常)
    Runnable的run方法中的异常只能在本类中处理,无法上抛

    9、wait、sleep、yield的区别
    wait会释放锁,其他线程竞争获得锁,用于线程间交互,可以通过notify/notifyall唤醒线程
    sleep一直持有锁,线程处于阻塞状态
    yield会释放线程所占有的CPU资源 会临时暂停当前正在执行的线程 ,来让有同样优先级的正在等待的线程有机会执行(谦让)。线程CPU资源的获取取决于调度器

    10、notify 和 notifyAll有什么区别?
    notify() 只随机唤醒一个 wait 线程
    notifyall() 唤醒所有 wait 线程 (移动到锁池中,等待锁竞争) 并允许他们争夺锁确保了至少有一个线程能继续运行

    11、为什么wait, notify 和 notifyAll这些方法不在thread类里面?
    JAVA提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获得。
    如果wait()方法定义在Thread类中,线程正在等待的是哪个锁就不明显了

    12、为什么wait和notify方法要在同步块中调用?
    如果不在synchronized块中会抛出monitor异常,
    wait/notify是线程之间的通信,他们存在竞态,必须保证在满足条件的情况下才进行wait
    如果不加锁的话,那么wait被调用的时候可能wait的条件已经不满足了,由于错误的条件下进行了wait,那么就有可能永远不会被notify到,所以需要强制wait/notify在synchronized中

    13、如何在两个线程间共享数据
    1 通过共享对象来实现这个目的 (obj里面定义的变量 ObjClass obj = new ObjClass(); new Thread(obj).start();) 多个线程共享一个变量
    2 使用像阻塞队列这样并发的数据结构 (synchronized 等 互斥)


    14、线程间如何通信
      一.syncrhoized加锁的线程的Object类的wait()/notify()/notifyAll()
      二.ReentrantLock类加锁的线程的Condition的await()/signal()/signalAll() (Condition condition = lock.newCondition())
          三.BlockingQueue阻塞队列 控制线程通信(共享对象丢到队列里)
          四.CountDownLatch 多个线程启动,也可以等待多个线程执行完后呼唤线程 (创建线程池共享变量) 等等

    15、Java中如何停止一个线程?
    调用interrupt方法是在当前线程中打了一个停止标志,当遇到阻塞(sleep/wait) 会抛出异常
    interrupt()与return结合使用也能实现停止线程 if(this.isInterrupted()) return;

    16、interrupt()、interrupted、isInterrupted区别 (线程关闭)
    interrupt()的作用是中断本线程("中断"状态,不会停止线程),当阻塞的地方(wait/sleep),会识别中断标记,并抛出InterruptedException后,清除中断标记(false)
    interrupted()判断线程是否被中断,并且清除中断状态
    isInterrupted()判断线程是否被中断
    interrupt()与return结合使用也能实现停止线程 if(this.isInterrupted()) return;

    17、有三个线程T1,T2,T3,怎么确保它们按顺序执行?
    一.可以把3个线程放到newSingleThreadExecutor(单例阻塞队列线程池)
    二.t1.statrt t2执行t1.join() t3执行t2.join()

    18、什么是线程安全?Vector是一个线程安全类吗?
    多线程和单线程每次运行结果和单线程运行的结果是一样的,就是线程安全的
    Vector 不是线程安全的,只能保证单个操作安全,复合操作同样不安全 (复合操作不具有原子性,中间被插入打断了)
    例 1: T1.getvector , T2.getvector
    2: T2.remove(1)
    3: T1.get(1) -- 抛出错误

    19、什么是FutureTask?
    可用于异步获取执行结果或取消执行任务的场景
    只有当运算完成的时候结果才能取回,如果运算尚未完成get方法将会阻塞.

    。。。。待完善。。。。

    群交流(262200309)
  • 相关阅读:
    codeforces1191B Tokitsukaze and Mahjong 哈希+思维
    洛谷P1608 路径统计 最短路变种 dijkstra算法
    自考新教材-p90_5(4)
    自考新教材-p90_5(3)
    自考新教材-p90_5(2)
    自考新教材-p90_5(1)
    自考新教材-p89_3
    自考新教材-p88_4(2)
    自考新教材-p88_4(1)
    自考新教材-p87_3
  • 原文地址:https://www.cnblogs.com/webster1/p/12246088.html
Copyright © 2020-2023  润新知