线程入门(一)

来源:互联网 发布:html中如何加入js语句 编辑:程序博客网 时间:2024/05/07 18:51

什么是线程?

一:程序、进程、线程的概念

1.程序(program)为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。
2.进程(process)程序的一次执行过程,或是正在运行的一个程序。动态过程:有它自身的产生、存在和消亡的过程
如:运行中的QQ,运行中的MP3播放器。程序是静态的,进程是动态的

3.线程(thread),进程可进一步细化为线程,是一个程序内部的一条执行路径。

若一个程序可同一时间执行多个线程,就是支持多线程的。
理解进程与线程的关系是学习线程的基础。进程是指在系统中正在运行的一个应用程序实例,它包括代码加载、执行和执行完毕一个完整的过程,也是进程本身从产生、发展到消亡的过程。多任务操作系统能够同时运行多个程序,即语序多个进程同时存在并运行。
线程是比进程更小的执行单位,是在进程基础上进行的进一步划分。所谓多线程是指一个进程在执行过程中可以产生多个同时存在、同时运行的线程。多线程机制可以合理利用资源,提高程序运行效率。一个进程至少包含一个线程,程序运行时即自动产生一个线程,如Java中主函数main就是在线程上运行的。除了主线程不再创建型的线程时,当前程序是单线程的。
多线程实现原理及与进程的关系图如下:
 

二:何时需要多线程?

程序需要同时执行两个或多个任务。
程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
需要一些后台运行的程序时。

线程实现

Java中实现多线程有两种凡是:继承Thred类和实现Runnable接口。

一:继承Thread类

Java中使用java.lang.Thread类控制线程,继承thread的类就可以被称为多线程操作类。需要注意,在继承Thread类的子类中重写Thread类中的run()方法,该方法为线程的主体。

继承Thread类调用线程流程:

1.继承Thread类

2.实现run()方法

3.调用start()方法,调用run()方法,启动线程执行线程主体。

package com.process;/** * thread类分析 * @author Administrator * *//* * 第一步继承了Thread类 */public class ThreadDemo extends Thread {private String name;public ThreadDemo(String name) {this.name = name;}/** * 第二步:重写thread类中run()方法 */@Overridepublic void run() {// TODO Auto-generated method stubfor(int i=1;i<=5;i++){System.out.println(name+"运行,i="+i);}}public static void main(String[] args) {/* * 这里只是调用run()方法,从而并未启用线程。可显而知,程序运行的结果一定是把 * 线程A的run方法走完,接着在走线程B的run方法 */new ThreadDemo("线程A").run();new ThreadDemo("线程B").run();}}


这是一个Error案例。对于菜鸟的我不得不把这些东西记住。可以看到程序的运行结果是先执行"线程A",然后在执行“线程B”,由此大众化问题即出现了:多线程不是同时执行的吗?,为什么还是顺序执行的!多线程同时存在、同时运行的特征体现在哪?。

答案:很简单!我并未启动线程,仅仅只是调用了两个对象的run()方法而已,先调A,执行完毕,在调B。

正确执行线程方法如下:仅仅只是把调用run()方法,改成了调用start()方法,也就是启动线程的正确方法。

package com.process;/** * thread类分析 * @author Administrator * *//* * 第一步继承了Thread类 */public class ThreadDemo extends Thread {private String name;public ThreadDemo(String name) {this.name = name;}/** * 第二步:重写thread类中run()方法 */@Overridepublic void run() {// TODO Auto-generated method stubfor(int i=1;i<=5;i++){System.out.println(name+"运行,i="+i);}}public static void main(String[] args) {/** * 而正确启用线程的方式第三步应该是什么呢? * 第三步:正确的来启用线程的方式是:调用从Thread类中继承而来的start()方法。 */new ThreadDemo("线程C").start();new ThreadDemo("线程D").start();}}

显而易见的,可以看得到资源的交错运行,即:哪个对象抢先获得cpu资源就可以先运行。

综以上两个打印结果可知,两个线程是交错运行的,即哪个线程对象抢先获取CPU资源就可以选运行,线程启动时通过start()方法调用run()方法,执行主体。

一段代码如需要在新线程中运行,该段代码就必须放在类的run()方法中,同时一个线程类对象只允许调用一次start()方法,多次调用会产生异常。

0 0
原创粉丝点击