Java线程.
2016-03-30 11:06
471 查看
Java 线程
基本概念
线程线程是程序执行的最小单元, 一个标准的线程由以下部分组成:
线程ID
当前指令指针(PC)
寄存器集合
堆栈
线程是进程中的一个实体, 是被系统独立调度和分派的基本单位, 线程不拥有系统资源, 只拥有运行中必须的资源, 但是它可以与同一进程中的其他线程共享进程所拥有的全部资源.
进程
进程是系统进行资源分配和调度的基本单位. 进程是线程的容器. 进程由以下部分组成:
程序段(存储处理器执行的代码)
数据段(存储变量和进程执行期间使用的动态分配的内存)
进程控制块(存储着活动过程调用的指令和本地变量)
进程具有以下特征:
动态性: 进程的实质是程序在多道程序系统中的一次执行过程, 进程是动态产生, 动态消亡的;
并发性: 任何进程都可以和其他进程并发执行;
异步性: 由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进;
结构特征:进程由程序、数据和进程控制块三部分组成。
线程的状态
创建线程(New) (继承Thread类, 实现Runnable接口, )就绪状态(Runnable) (调用线程对象的start()方法)
运行状态(Running) (就绪线程获得CPU资源, 执行程序代码)
阻塞状态(Blocked) (线程因某些原因放弃CPU使用权, 暂停运行)
等待阻塞: 运行的线程执行
wait()方法, JVM将线程放入等待池中
同步阻塞: 运行的线程在获取对象的同步锁时, 如果同步锁被占用, 则JVM会把线程放入锁池中
其他阻塞: 运行线程执行
sleep()或
join()方法, 或者发出I/O请求, JVM会把该线程置为阻塞状态.当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态
死亡状态(Dead) 线程执行完了或者因异常退出了run()方法, 该线程结束生命周期
进程的状态
创建进程(New) 创建进程分为以下两步完成:为一个新进程创建PCB, 并填写必要的管理信息
把该进程转入就绪状态并插入就绪队列之中
就绪状态(Ready) 进程已经分配到除了CPU以外的必要资源, 只要在获得CPU进程就转到执行状态
执行状态(Running) 进程分配到CPU, 执行程序
阻塞状态(Blocked) 进程因为某些原因无法继续执行, 放弃对CPU的使用权
挂起状态 引起挂起状态的原因有以下几点:
终端用户的请求
父进程请求
负荷调节的需要
操作系统的需要
终止状态(Dead) 等待操作系统进行善后处理,然后将其PCB清零,并将PCB空间返还系统。当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结,它将进入终止状态。进入终止态的进程以后不能再执行,但在操作系统中依然保留一个记录,其中保存状态码和一些计时统计数据,供其它进程收集。一旦其它进程完成了对终止状态进程的信息提取之后,操作系统将删除该进程。
示例代码
创建线程
继承Thread类定义Thread的子类, 重写run()方法
创建Thread子类的实例
调用Thread子类的实例的start()方法, 启动线程
public class Thread001 { public static void main(String []args) { System.out.println("main thread name is:" + Thread.currentThread().getName()); DemoExtendsThread thread1 = new DemoExtendsThread("DemoExtendsThread"); thread1.start(); } } class DemoExtendsThread extends Thread { public DemoExtendsThread(String name) { super(name); } @Override public void run() { System.out.println("DemoExtendsThread thread name is:" + Thread.currentThread().getName()); System.out.println("created thread by extend Thread class"); } }
实现Runnable接口
定义实现Runnable接口的实现类, 重写run()方法
创建Runnable实现类的实例
创建Thread类的实例, 并将Runnable实现类的实例作为参数传递给Thread类的构造函数
调用Thread类的实例的run()方法
public class Thread002 { public static void main(String []args) { DemoImplementRunable thread2 = new DemoImplementRunable(); Thread thread = new Thread(thread2,"DemoImplementRunable"); thread.start(); } } class DemoImplementRunable implements Runnable { @Override public void run() { System.out.println("DemoImplementRunable thread name is:" + Thread.currentThread().getName()); System.out.println("create thread by implements Runnable"); } }
通过Callable和Future创建线程
定义实现Callable接口的类, Callable可以传递一个泛型, 即返回值的类型
创建Callable实现类的实例, 创建FutureTask类实例, 并将Callable实现类的实例传递给FutureTask类实例
创建Thread类的实例, 将FutureTask类实例传递给Thread实例
调用Thread实例的start()方法启动线程
public class Thread003 { public static void main(String []args) { System.out.println("main thread name is:" + Thread.currentThread().getName()); DemoImplementCallable thread3 = new DemoImplementCallable(); FutureTask<Integer> futureTask = new FutureTask<>(thread3); new Thread(futureTask, "DemoImplementCallable").start(); try { System.out.println("子线程返回的值:" + futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); 4000 } } } class DemoImplementCallable implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println("DemoImplementCallable thread name is:" + Thread.currentThread().getName()); System.out.println("create thread by implements Callable"); return 1; } }
run()与start()的区别
在程序中直接调用run()方法时, run()方法中的代码并不会在新的线程执行, 而是在当前线程执行.调用start()方法时才会创建新的线程, run()方法中的代码才会在新的线程中执行.
public class Thread004 { public static void main(String []args) throws InterruptedException { System.out.println("main method is starting!"); System.out.println("main thread name is:" + Thread.currentThread().getName()); ThreadRunAndStart threadRunAndStart = new ThreadRunAndStart(); // 1. 直接调用run()方法 threadRunAndStart.run(); // 2. 调用Thread的start()方法 new Thread(threadRunAndStart, "ThreadRunAndStart").start(); System.out.println("main method is over!"); } } class ThreadRunAndStart implements Runnable { @Override public void run() { for (int i=0; i<100; i++) { System.out.println("run in " + Thread.currentThread().getName() + ", i=" + i); } } }
相关文章推荐
- Spring MVC 注解方式 静态类 注入bean
- 100天JAVA学习计划03-浅谈方法
- JAVA中生成Excel方法
- Ubuntu14.04下安装配置openJDK1.7
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
- javaweb学习总结(九)—— 通过Servlet生成验证码图片
- eclipse 修改jsp页面不能立即有效果问题
- springmvc注解和参数传递
- SpringMvc 使用poi导入导出Excel
- eclipse设置
- 归并排序(Java描述)
- struts2的execAndWait拦截器
- 项目经验之springmvc单元测试
- Spring中RedirectAttributes说明
- Java NIO系列教程(十二) Java NIO与IO
- ExecException: Process'command'E:\jdk1.8.0_60\bin\java.exe'' finished with non-zero exit value 2
- Spring中拦截/和拦截/*的区别 - 不能访问到返回的JSP - 访问静态资源(jpg,js等)
- Java NIO系列教程(十一) Pipe
- Java多线程系列目录(共43篇)
- Java NIO系列教程(十) Java NIO DatagramChannel