java面试题解惑 之 多线程
1,多线程
线程或者说多线程,是我们处理多任务的强大工具。
线程与进程的区别:[/size]
线程和进程是不同的,每个进程都是一个独立运行的程序,拥有自己的变量,且不同进程间的变量不能共享;而线程是运行在进程内部的,每个正在运行的进程至少有一个线程,而且不同的线程之间可以在进程范围内共享数据。也就是说进程有自己独立的存储空间,而线程是和它所属的进程内的其他线程共享一个存储空间。线程的使用可以使我们能够并行地处理一些事情。线程通过并行的处理给用户带来更好的使用体验,比如你使用的邮件系统(outlook、Thunderbird、foxmail等),你当然不希望它们在收取新邮件的时候,导致你连已经收下来的邮件都无法阅读,而只能等待收取邮件操作执行完毕。这正是线程的意义所在。
java中有两中方式实现多线程,一种是继承Thread类,一种实现Runnable接口线程启动是用start方法,而非run方法。
线程状态的具体信息如下:
1. NEW(新建状态、初始化状态):线程对象已经被创建,但是还没有被启动时的状态。
这段时间就是在我们调用new命令之后,调用start()方法之前。
2. RUNNABLE(可运行状态、就绪状态):在我们调用了线程的start()方法之后线程所
处的状态。处于RUNNABLE状态的线程在JAVA虚拟机(JVM)上是运行着的,但是它可
能还正在等待操作系统分配给它相应的运行资源以得以运行。
3. BLOCKED(阻塞状态、被中断运行):线程正在等待其它的线程释放同步锁,以进
入一个同步块或者同步方法继续运行;或者它已经进入了某个同步块或同步方法,在运行的
过程中它调用了某个对象继承自java.lang.Object的wait()方法,正在等待重新返回这个同步块或同步方法。
4. WAITING(等待状态):当前线程调用了java.lang.Object.wait()、
java.lang.Thread.join()或者java.util.concurrent.locks.LockSupport.park()三个中的任意一个方法,
正在等待另外一个线程执行某个操作。比如一个线程调用了某个对象的wait()方法,正在等
待其它线程调用这个对象的notify() 或者notifyAll()(这两个方法同样是继承自Object类)方
法来唤醒它;或者一个线程调用了另一个线程的join()(这个方法属于 Thread类)方法,正在等待这个方法运行结束。
5. TIMED_WAITING(定时等待状态):当前线程调用了 java.lang.Object.wait(long
timeout)、java.lang.Thread.join(long
millis)、java.util.concurrent.locks.LockSupport.packNanos(long
nanos)、java.util.concurrent.locks.LockSupport.packUntil(long deadline)四个方法中的任意一个,
进入等待状态,但是与WAITING状态不同的是,它有一个最大等待时间,即使等待的条件
仍然没有满足,只要到了这个时间它就会自动醒来。
6. TERMINATED(死亡状态、终止状态):线程完成执行后的状态。线程执行完run()方
法中的全部代码,从该方法中退出,进入TERMINATED状态。还有一种情况是run()在运行
过程中抛出了一个异常,而这个异常没有被程序捕获,导致这个线程异常终止进入
TERMINATED状态。
在Java5.0及以上版本中,线程的全部六种状态都以枚举类型的形式定义在java.lang.Thread
类中了,代码如下:
import java.util.concurrent.*;public class ExecutorTest {public static void main(String[] args) throws InterruptedException,ExecutionException {ExecutorService es = Executors.newSingleThreadExecutor();Future fr = es.submit(new RunnableTest());// 提交任务Future fc = es.submit(new CallableTest());// 提交任务// 取得返回值并输出System.out.println((String) fc.get());// 检查任务是否执行完毕if (fr.isDone()) {System.out.println("执行完毕-RunnableTest.run()");} else {System.out.println("未执行完-RunnableTest.run()");}// 检查任务是否执行完毕if (fc.isDone()) {System.out.println("执行完毕-CallableTest.run()");} else {System.out.println("未执行完-CallableTest.run()");}// 停止线程池服务es.shutdown();}}class RunnableTest implements Runnable {public void run() {System.out.println("已经执行-RunnableTest.run()");}}class CallableTest implements Callable {public Object call() {System.out.println("已经执行-CallableTest.call()");return "返回值-CallableTest.call()";}}