黑马程序员技术交流社区
标题:
关于多线程的问题
[打印本页]
作者:
唐巍
时间:
2012-3-14 01:39
标题:
关于多线程的问题
进程和线程有什么区别?在创建线程时,不管继承Thread类还是实现Runnable接口为什么都要覆盖Thread类中的run方法?继承Thread类和实现Runnable接口创建线程时两者有什么不同?用哪一种创建线程更好呢?
作者:
王思兰
时间:
2012-3-14 02:08
方法 run 的常规协定是,它可能执行任何所需的操作。
可以看看API,上面有很多解释
作者:
贠(yun)靖
时间:
2012-3-14 02:26
进程:是一个正在执行中的程序。
每一个进程执行都有一个执行顺序,该顺序是一个执行路径,
或者叫一个控制单元。
线程:就是进程中的一个独立的控制单元。
线程在控制着进程的执行。
一个进程中至少有一个线程。
start()方法的作用:1,启动线程 2,调用run()方法
多线程特点:随机性,谁抢到谁执行,至于执行多长时间由cpu说了算。
原因是多个线程都获取cpu的执行权,cpu执行到谁,谁就运行。
注:在某一个时刻,只能有一个程序在运行(多核除外)
可以理解为多线程的运行行为时在互相抢夺cpu的执行权。
为什么要覆盖run方法?
THread类用于描述线程。该类就定义了一个功能,用于存储线程
的运行代码,该存储功能就是run方法。也就是说thread类中的
run方法是用于存储线程要运行的代码。所以复写run方法就是将
自定义的代码存储在run方法中,让线程运行。
Runnable接口
1,定义类实现Runnable接口
2,覆盖Runnable接口中的run方法
将线程要运行的代码存放在run方法中。
3,通过Thread类建立线程对象。
4,将Runnable接口的子类对象作为实际参数传递给Ttread类的构造函数
为什么要将Runnable接口的子类对象传递给thread的构造函数?
因为,自定义的run方法所属的对象是Runnable接口的子类对象,
所以要让线程去指定指定对象的run方法,就必须明确该run方法所属的对象。
而thread类的构造方法之一是 Thread(Runnable r){}
5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
实现方式和继承方式的区别
实现方式的好处:避免了单继承的局限性。推荐使用实现方式。
继承方式线程代码存放在Thread子类run方法中,而实现方法存放在
就扣的子类run方法中。
作者:
a504079589
时间:
2012-3-14 02:35
进程就是一个运行中的程序, 一个进程中可以有多个线程,线程是CPU调度和分派的基本单位, 可以理解为线程就是程序运行中的一条路径;
多个线程并发执行, 提高程序运行效率;
Thread 要继承, 而Runnable 是实现, 两者的区别是: 1: 继承Thread: 线程代码存放在Thread子类的run()方法之中; 定义类继承Thread, 重写run()方法, 创建对象调用start()方法,开启线程并调用run()方法;
2: 实现Runnable: 线程代码存放在接口子类的run()方法之中; 实现Runnable 接口,重写Runnable接口中的run()方法,将要运行的代码存放在run()方法中, 通过Thread类建立线程对象,将Runnable的子类对象作为实参穿给Thread的构造函数, 调用Thread类的start()方法开启线程并调用Runnable子类的run()方法; 之所以要将Runnable的子类对象船给Thread,就是因为run()方法所属的对象是Runnable的子类对象, 所以要让线程去指定对象的run()方法, 就必须明确该run()方法所属对象;
我建议用实现的方式创建线程, 因为实现的方式避免了单继承的极限性;
作者:
崔岩
时间:
2012-3-14 08:35
本帖最后由 崔岩 于 2012-3-14 08:39 编辑
我用点通俗的话给你讲吧,联系下现实生活。进程呢,可以理解为一个应用程序。比如一场足球赛模拟程序,整个程序就是一个进程。而这个程序中呢,肯定要有若干个球员实例,每个球员就是一个进程。那么对应到程序里呢,球员就是thread的子类。 你说的关于thread 和 runnable的区别。 我们还是结合球赛来讲,球场上肯定只有一个足球对吧?那么这个足球就是一个所有进程共用的资源。每个球员必须要有踢球这个方法,这个方法必须要调用足球这个资源,因此问题就来了,当一个进程(球员)拿到球以后,其他的进程必须要等他主动或者被动的释放这个球,才能让自己的踢球方法运行起来。这也就是进程的互斥问题。 下面我们用面向对象的方法来设计各个对象。球员: public class player extend Thread 足球: public class football implement Runnable { private Object obj ; run()//代表球被获取的方法,并且在这里加同步锁obj,序运行时候,必须只new一个足球实例,new出多个球员,而Thread(runnable)类的构造函数中,恰巧可以传一个runnable对象进去,此例中就是new player(football)。这样可以保证足球只有一个,把球作为参数传给球员,在调用player.start方法。因此obj对象实例也只有一个,所有球员使用的都是同一个锁,这样才能保证球员间的互斥,同时只有一个球员拿到球。 run方法里就是我们需要对共享资源(足球)进行操作的代码。 试想下如果把锁声明在thread里,那new出来多个对象以后,大家用的不是一个锁,不就实现不了同步了么。
作者:
黄奇耀
时间:
2012-3-14 08:45
1.进程和线程的区别:
进程至少包含一个线程,它可以有多个线程。进程就是程序运行时的名字,它是程序的运行时的一个标识。
线程就是控制程序运行。程序的运行其实是线程的执行。
2.Thread和Runnable都要重写run()方法
api规定Thread要继承Runnable接口,而Runnable接口下有个run()方法,所以这两个都是重写run()方法。
3.创建线程有何不同
Thread使用方法:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
Runnable使用方法:
public class RunnableTest implements Runnable {
public void run() {
....
}
}
最后都用start()方法启动线程。
4.用哪一种创建线程更好
Thread:
Thread子类无法再从其它类继承(java语言的单继承),编写简单,run()方法的当前对象就是线程对象,可直接操作。
Runnable:
可以将CPU,代码和数据分开,形成清晰的模型;线程体run()方法所在的类可以从其它类中继承一些有用的属性和方法;有利于保持程序的设计风格一致。
各有优缺点。
作者:
宋洪祥
时间:
2012-3-14 09:23
从概念上:
进程:一个程序对一个数据集的动态执行过程,是分配资源的基本单位。
线程:一个进程内的基本调度单位。
线程的划分尺度小于进程,一个进程包含一个或者更多的线程。
从执行过程中来看:
进程:拥有独立的内存单元,而多个线程共享内存,从而提高了应用程序的运行效率。
线程:每一个独立的线程,都有一个程序运行的入口、顺序执行序列、和程序的出口。但是线程不能够独立的执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看:(重要区别)
多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但是,操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理及资源分配。
创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法,另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。
使用Runnable接口创建线程
1.可以将CPU,代码和数据分开,形成清晰的模型
2.线程体run()方法所在的类可以从其它类中继承一些有用的属性和方法
3.有利于保持程序的设计风格一致
直接继承Thread类创建对象
1.Thread子类无法再从其它类继承(java语言单继承)。
2.编写简单,run()方法的当前对象就是线程对象,可直接操作。
在实际应用中,几乎都采取第一种方式
作者:
OMG
时间:
2012-3-14 10:46
我想您的疑问有以下几点:
1,为什么会出现进程和线程的概念?
2,为什么必须把要执行的代码封装到run()方法中?
3,用类好还是用接口好?
首先,进程和线程,这需要提到cpu。cpu其实不是同时处理多个软件,而是一次只能执行一个程序中的一个对象的代码,并且做瞬间切换,感官上觉得好像是同时运行而已。当我们打开很多页码,同时听歌,下载,复制,移动,玩游戏,为什么会出现卡的现象?对象多,cpu切换周期过长所致。
其次,进程是一个程序,而线程是一个对象。从效率上来说,要快速完成任务,最好是让多个对象共同完成;
再次,为什么要把代码封装到run方法中呢?要实现多个对象独立运行,是需要对对象进行处理的,而对应的处理办法已经封装到start()方法中。而start()方法只认run()方法,只处理run()中的内容,所以,必须把要执行的代码写在run方法中。
最后,继承Thread类好还是实现RunnAble好呢?这是类与接口的区别,请问,如果你写的这个类,已经有父类了,你还能继承Thread类吗?就不能了。还好,可以实现Runnable接口。所以,在定义一个类时,还不清楚它是否要继承某个类的话,那就是用Runnable接口吧。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2