Java线程、多线程与线程池总结

先看几个概念: 线程:进程中负责程序执行的执行单元 。一个进程中至少有一个线程 。
多线程:解决多任务同时执行的需求,合理使用CPU资源 。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性 。
线程池:基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理 。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源 。
● 线程
创建线程的两种方式:
一、继承Thread类,扩展线程 。class DemoThread extends Thread {@Overridepublic void run() {super.run();// Perform time-consuming operation...}}DemoThread t = new DemoThread();t.start();

  • 继承Thread类,覆盖run()方法 。
  • 创建线程对象并用start()方法启动线程 。
面试题
  • 1)线程和进程有什么区别?
一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用 。而线程是在进程中执行的一个任务 。线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务 。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间 。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据 。
  • 2)如何在JAVA中实现线程?
创建线程有两种方式: 一、继承 Thread 类,扩展线程 。二、实现 Runnable 接口 。
  • 3)Thread 类中的 start() 和 run() 方法有什么区别?
调用 start() 方法才会启动新线程;如果直接调用 Thread 的 run() 方法,它的行为就会和普通的方法一样;为了在新的线程中执行我们的代码,必须使用 Thread.start() 方法 。
扩展Android 系统接口 HandlerThread 继承了 Thread,它是一个可以使用 Handler 的 Thread,一个具有消息循环的线程 。run()方法中通过 Looper.prepare() 来创建消息队列,通过 Looper.loop() 来开启消息循环 。可以在 run() 方法中执行耗时的任务,而 HandlerThread 内部创建了消息队列外界需要通过 Handler 的方式来通知 HandlerThread 执行一个具体任务;HandlerThread 的 run() 方法是一个无限的循环,可以通过它的 quite() 或 quitSafely() 方法来终止线程的执行;
二、实现Runnable接口 。public class DemoActivity extends BaseActivity implements Runnable {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Thread t = new Thread(this);t.start();}@Overridepublic void run() {}}面试题
  • 1)用 Runnable 还是 Thread ?
我们都知道可以通过继承 Thread 类或者调用 Runnable 接口来实现线程,问题是,创建线程哪种方式更好呢?什么情况下使用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口 。所以如果你要继承其他类,当然是调用Runnable接口更好了 。
  • 2)Runnable 和 Callable 有什么不同?
Runnable 和 Callable 都代表那些要在不同的线程中执行的任务 。Runnable 从 JDK1.0 开始就有了,Callable 是在 JDK1.5 增加的 。它们的主要区别是 Callable 的 call() 方法可以返回值和抛出异常,而 Runnable 的 run() 方法没有这些功能 。Callable 可以返回装载有计算结果的 Future 对象 。
?注意:这面第二个面试题主要是为了引出下面的扩展,原谅我这样为难人的出场 。
扩展先看一下 Runnable 和 Callable 的源码
public interface Runnable {public void run();}public interface Callable<V> {V call() throws Exception;}可以得出:
1)Callable 接口下的方法是 call(),Runnable 接口的方法是 run() 。2)Callable 的任务执行后可返回值,而 Runnable 的任务是不能返回值的 。3)call() 方法可以抛出异常,run()方法不可以的 。4)运行 Callable 任务可以拿到一个 Future 对象,表示异步计算的结果 。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果 。通过 Future 对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果 。
但是,但是,凡事都有但是嘛...
单独使用 Callable,无法在新线程中(new Thread(Runnable r))使用,Thread 类只支持 Runnable 。不过 Callable 可以使用 ExecutorService (又抛出一个概念,这个概念将在下面的线程池中说明) 。
【Java线程、多线程与线程池总结】上面又提到了 Future,看一下 Future 接口:
public interface Future<V> {boolean cancel(boolean mayInterruptIfRunning);boolean isCancelled();boolean isDone();V get() throws InterruptedException, ExecutionException;V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;}


推荐阅读