26、什么是线程组,为什么在 Java 中不推荐使用?
线程组和线程池是两个不同的概念,他们的作用完全不同,前者是为了方便线程 的管理,后者是为了管理线程的生命周期,复用线程,减少创建销毁线程的开销。
27、为什么使用 Executor 框架比使用应用创建和管理线程好?
为什么要使用 Executor 线程池框架 :1、每次执行任务创建线程 new Thread()比较消耗性能,创建一个线程是比较耗 时、耗资源的。 2、调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的 创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪,还有线程 之间的频繁交替也会消耗很多系统资源。 3、直接使用 new Thread() 启动的线程不利于扩展,比如定时执行、定期执行、 定时定期执行、线程中断等都不便实现。 使用 Executor 线程池框架的优点 1、能复用已存在并空闲的线程从而减少线程对象的创建从而减少了消亡线程的开 销。 2、可有效控制最大并发线程数,提高系统资源使用率,同时避免过多资源竞争。 3、框架中已经有定时、定期、单线程、并发数控制等功能。 综上所述使用线程池框架 Executor 能更好的管理线程、提供系统资源使用率。
28、java 中有几种方法可以实现一个线程?
继承 Thread 类 实现 Runnable 接口 实现 Callable 接口,需要实现的是 call() 方法
29、如何停止一个正在运行的线程?
使用共享变量的方式 在这种方式中,之所以引入共享变量,是因为该变量可以被多个执行相同任务的 线程用来作为是否中断的信号,通知中断线程的执行。 使用 interrupt 方法终止线程 如果一个线程由于等待某些事件的发生而被阻塞,又该怎样停止该线程呢?这种 情况经常会发生,比如当一个线程由于需要等候键盘输入而被阻塞,或者调用 Thread.join()方法,或者 Thread.sleep()方法,在网络中调用 ServerSocket.accept()方法,或者调用了 DatagramSocket.receive()方法时,都 有可能导致线程阻塞,使线程处于处于不可运行状态时,即使主程序中将该线程 的共享变量设置为 true,但该线程此时根本无法检查循环标志,当然也就无法立 即中断。这里我们给出的建议是,不要使用 stop()方法,而是使用 Thread 提供的 interrupt()方法,因为该方法虽然不会中断一个正在运行的线程,但是它可以使一 个被阻塞的线程抛出一个中断异常,从而使线程提前结束阻塞状态,退出堵塞代 码。
30、notify()和 notifyAll()有什么区别?
当一个线程进入 wait 之后,就必须等其他线程 notify/notifyall,使用 notifyall,可 以唤醒所有处于 wait 状态的线程,使其重新进入锁的争夺队列中,而 notify 只能 唤醒一个。 如果没把握,建议 notifyAll,防止 notigy 因为信号丢失而造成程序异常。