黑马程序员-多线程部分(一.创建)
2015-10-11 14:02
225 查看
——- android培训、java培训、期待与您交流! ———
第一点: 什么是进程?什么是线程?
任何一个应用程序开启后都是一个进程,进程是由window/linux系统启动的。线程是进程开启后运行的操作控制单元,或者称为执行路径, 一个进程至少有一个线程。对于任何一个java程序,实际上开启的是两个线程,一个是main顺序执行的顺序线程,一个是系统自带的gc垃圾回收线程。这样做的好处是一方面保证了内存的空间,一方面保证了运行速度不受影响。
第二点:多线程的理解?
当一个进程中开启多个线程时,显示的为这多个线程同时在执行,而实际上如果只有一个CPU处理器时,CPU是随机选择执行某一个线程的,由于CPU高速切换的特性,看起来好像多个线程在同时执行,这是看哪个线程率先抢占CPU的执行权,但在某一时刻,一个CPU是只执行一个线程的。 多线程就是一个线程里面有两个或两个以上线程可以一起执行,都具备CPU执行资格,也都可以轮流运行。
第三点:多线程的作用?
多线程可以使多个程序同时运行,提高了运行效率。
明白以上三点,首先我们学校多线程的创建方式。
一个线程的创建方式有两种:
步骤二:覆写run方法
步骤三:实例化对象,调用start方法。
运行结果如下:
main线程和test线程交替运行。
在这里,多线程执行的是run()方法里面的代码块,调用start()方法有两个作用,一是开启该线程,二是调用run()方法。此处不应该直接调用run()方法,如下代码会出现错误:
运行结果:
显示为先执行test的run方法,后执行main以后的代码,此为单线程。
需要说明一点:如果没有调用start方法,实际上等于没有开启多线程,只是简单的在main线程中调用run方法而已,实际上只有一个main线程,而非是多线程。
步骤二:覆写runnable接口中的run方法 。
步骤三:实例化实现runnable接口的子类对象
步骤四:实例化Thread类,并把实现runnable接口的子类对象传递到构造方法中
步骤五:调用启动线程方法start()
在这里,与Thread唯一的不同是,在Thread实例化时,将runnable接口的子类传入到构造方法中即可实现。
以上两种方法为简单的创建多线程,那么二者有什么区别和联系呢?
1). 如果该类继承了其他类,则不可继承Thread类;或者继承了Thread类则不可继承其他类,而使用runnable接口则不会出现这种情况,避免了单继承的局限。
2). 使用runnable接口,则可以实现资源共享。不用定义为static即可。
一般情况,建议使用runnable接口的方法开启线程。
第一点比较容易理解,下面看一下第二点,利用代码说明。
例子:一共50张票,4个窗口同时买票。
首先用Thread实现:
运行结果如下:
结果显示,四个线程分别执行了50张票,没有共享数据,造成数据错误。
在此用Runnable实现:
运行结果如下:
而一个Runnable子类被传递到四个线程中,可以共享数据,从而避免了数据错误。
好了,到此为止,多线程创建部分已经完成了,下一集介绍多线程的多线程的数据安全问题,利用线程同步来解决。敬请期待。 本人也是初学者,有什么问题请指出,共同商讨。
学习多线程之前,我们需要知道为什么要学习多线程?首先需要明确以下三点内容:
第一点: 什么是进程?什么是线程?
任何一个应用程序开启后都是一个进程,进程是由window/linux系统启动的。线程是进程开启后运行的操作控制单元,或者称为执行路径, 一个进程至少有一个线程。对于任何一个java程序,实际上开启的是两个线程,一个是main顺序执行的顺序线程,一个是系统自带的gc垃圾回收线程。这样做的好处是一方面保证了内存的空间,一方面保证了运行速度不受影响。
第二点:多线程的理解?
当一个进程中开启多个线程时,显示的为这多个线程同时在执行,而实际上如果只有一个CPU处理器时,CPU是随机选择执行某一个线程的,由于CPU高速切换的特性,看起来好像多个线程在同时执行,这是看哪个线程率先抢占CPU的执行权,但在某一时刻,一个CPU是只执行一个线程的。 多线程就是一个线程里面有两个或两个以上线程可以一起执行,都具备CPU执行资格,也都可以轮流运行。
第三点:多线程的作用?
多线程可以使多个程序同时运行,提高了运行效率。
明白以上三点,首先我们学校多线程的创建方式。
一个线程的创建方式有两种:
(一)使用Thread类完成,创建步骤如下:
步骤一:一个子类继承Thread类步骤二:覆写run方法
[code]class Test extends Thread { void run() { for(int i=0;i<100;i++) { System.out.println("test......."+i); } } }
步骤三:实例化对象,调用start方法。
[code]public class ThreadDemo { public static void main(String args[]) { Test test = new Test(); test.start(); for(int i=0;i<90;i++) { System.out.println("main......."+i); } } }
运行结果如下:
main线程和test线程交替运行。
在这里,多线程执行的是run()方法里面的代码块,调用start()方法有两个作用,一是开启该线程,二是调用run()方法。此处不应该直接调用run()方法,如下代码会出现错误:
[code]public class ThreadDemo { public static void main(String args[]) { Test test = new Test(); test.run(); for(int i=0;i<90;i++) { System.out.println("main......."+i); } } }
运行结果:
显示为先执行test的run方法,后执行main以后的代码,此为单线程。
需要说明一点:如果没有调用start方法,实际上等于没有开启多线程,只是简单的在main线程中调用run方法而已,实际上只有一个main线程,而非是多线程。
(二)实现runnable接口,开启线程。 实现步骤如下 :
步骤一:实现runnable接口步骤二:覆写runnable接口中的run方法 。
[code]class Test implements Runnable { public void run() { for(int i=0;i<100;i++) { System.out.println("test......."+i); } } }
步骤三:实例化实现runnable接口的子类对象
步骤四:实例化Thread类,并把实现runnable接口的子类对象传递到构造方法中
步骤五:调用启动线程方法start()
[code]public class ThreadDemo { public static void main(String args[]) { Test test = new Test(); Thread t = new Thread(test); t.start(); for(int i=0;i<90;i++) { System.out.println("main......."+i); } } }
在这里,与Thread唯一的不同是,在Thread实例化时,将runnable接口的子类传入到构造方法中即可实现。
以上两种方法为简单的创建多线程,那么二者有什么区别和联系呢?
1). 如果该类继承了其他类,则不可继承Thread类;或者继承了Thread类则不可继承其他类,而使用runnable接口则不会出现这种情况,避免了单继承的局限。
2). 使用runnable接口,则可以实现资源共享。不用定义为static即可。
一般情况,建议使用runnable接口的方法开启线程。
第一点比较容易理解,下面看一下第二点,利用代码说明。
例子:一共50张票,4个窗口同时买票。
首先用Thread实现:
[code]class Test extends Thread { private int ticket = 50; public void run() { while(true) { if(ticket>0) { System.out.println("ticket......."+ticket--); } } } }
[code]public class ThreadDemo { public static void main(String args[]) { Test t1 = new Test(); Test t2 = new Test(); Test t3 = new Test(); Test t4 = new Test(); t1.start(); t2.start(); t3.start(); t4.start(); } }
运行结果如下:
结果显示,四个线程分别执行了50张票,没有共享数据,造成数据错误。
在此用Runnable实现:
[code]class Test implements Runnable { private int ticket = 50; public void run() { while(true) { if(ticket>0) { System.out.println("ticket......."+ticket--); } } } }
[code]public class ThreadDemo { public static void main(String args[]) { Test test = new Test(); Thread t1 = new Thread(test); Thread t2 = new Thread(test); Thread t3 = new Thread(test); Thread t4 = new Thread(test); t1.start(); t2.start(); t3.start(); t4.start(); } }
运行结果如下:
而一个Runnable子类被传递到四个线程中,可以共享数据,从而避免了数据错误。
好了,到此为止,多线程创建部分已经完成了,下一集介绍多线程的多线程的数据安全问题,利用线程同步来解决。敬请期待。 本人也是初学者,有什么问题请指出,共同商讨。
相关文章推荐
- 黑马程序员—面向对象知识汇总
- 黑马程序员--NSNumber的使用
- C# 程序员最常犯的 10 个错误
- 黑马程序员--OC中常见的结构体
- 黑马程序员———java 集合框架
- 黑马程序员--集合
- 黑马程序员--NSDictionary的使用
- 黑马程序员——IO流
- 黑马程序员——正则
- 黑马程序员——反射机制
- 黑马程序员——Integer与int的种种比较你知道多少?
- 黑马程序员——多线程
- 黑马程序员——String
- 黑马程序员——面向对象三大特性
- 黑马程序员——继承和重写的区别
- 黑马程序员——异常
- 黑马程序员——集合
- 黑马程序员——面向对象笔记
- 黑马程序员--OC之类的封装继承多态使用技巧
- 黑马程序员--NSString