线程的实例讲解
来源:互联网 发布:机械设计三维图软件 编辑:程序博客网 时间:2024/06/05 20:51
上一节我们讲解了进程和线程的区别,概念比较繁重,可能读者会出现大脑昏晕的状态,接下来我就实例讲解一下具体的使用,供大家更加深入的理解概念:
(一)操作进程:在Java代码中如何运行一个进程,主要有两种方式:
实现功能:在Java程序中如何开启一个进程:运行记事本程序!
方式一:Runtime类的exec()方法即可开启一个进程(每一个应用程序中都会有一个Runtime类的实例对象,这个类构造函数私有,对象单例)
//方式一:使用Runtime类的exec()方法Runtime runtime = Runtime.getRuntime();try {runtime.exec("notepad");} catch (IOException e) {e.printStackTrace();http://blog.csdn.net/super_yc/article/details/73294203}
方式二:ProcessBuilder 类中的start()方法就可以开启一个进程:
//方式二:ProcessBuilder的start()方法ProcessBuilder pb = new ProcessBuilder("notepad");try {pb.start();} catch (IOException e) {e.printStackTrace();}
(二)操作线程,创建和启动线程在传统上有两种方式:
方式一:继承Thread类(本质上Thread 类也实现了Runnable 接口)
步骤:
1)定义一个类继承于java.lang.Thread类;
2)在SubThread类中覆盖Thread类中的run()方法;
3)在run()方法中编写需要执行的操作------->run()方法里即为线程执行体;
4)在main()方法(线程)中,创建线程对象,并启动线程!
创建线程类对象 SubThread st = new SubThread();
调用线程对象中的start()方法st.start();//启动一个线程
注意:在创建线程对象后,直接调用run()方法,依然只有一个线程,就是主线程,并没有开启一个新线程;和普通方法调用等同,依然串行执行!
方式二:实现Runnable接口;
步骤:
1)定义一个类实现接口java.lang.Runnable接口;
2)在Sub类中覆盖Runnable接口中的run()方法;
3)在run()方法中编写需要执行的操作------->run()方法里,线程执行体;
4)在main()方法中创建线程对象,并且启动线程!
创建线程类对象: Thread t = new Thread( new Sub() );
调用线程对象的start()方法:t.start();
使用实现Runnable接口创建线程,先判断target不为空,直接调用实现类中的run()方法!(运行时,动态绑定,多态实现!)
@Override public void run() { if (target != null) { target.run(); } }
注意:默认的Thread.run()就是直接调用内部的Runabble接口,因此使用Runnable接口告诉线程该做什么,比较合理。要使用Thread(Runnable target)的构造函数,实现Runnable接口的类,想要开启一个线程,必然要调用start()方法,但Runnable接口中没有此方法,所以必须要借助Thread类的API来启动线程!(Thread本质上也是Runabble接口的实现类)
【示例】
/*
* 案例:存在50个苹果,现在有请三个童鞋(小A,小B,小C)上台表演吃苹果,因为A,B,C三个人可以同 * 时吃苹果,此时得使用多线程技术来实现这个案例,
* 分析:可以定义三个线程对象,并启动线程,每个同学吃苹果的时候:先展示自己拿到手上苹果的编 * 号,如1,2,3,4.....50,再吃掉苹果 (意味着苹果总数减少一个)
*/
方式一:可以使用继承Thread类的方式来实现(继承执行失败,不能实现其功能!)
//方式一:可以使用继承Thread类的方式来实现;public class EatAppleGame {public static void main(String[] args) {//创建申请那个线程(同学),吃苹果Person p1 = new Person("小A");Person p2 = new Person("小B");Person p3 = new Person("小C");p1.start();p2.start();p3.start();}}class Person extends Thread{//表示苹果总数private int num = 50;public Person(String name) {super(name);}public void run(){for (int i = 0; i < 50; i++) {if(num > 0){System.out.println(super.getName() + "吃了编号为:" + num-- + "的苹果!");}}}}
方式二:通过继承Thread类来实现临界资源的共享:(可以实现资源共享,Thread类本质上也实现了Runnable接口)
//方式二:可以使用继承Thread类的方式来实现;public class EatAppleGame {public static void main(String[] args) {//创建申请那个线程(同学),吃苹果,创建三个对象,资源不能共享Person p = new Person();new Thread(p,"小A").start();new Thread(p,"小B").start();new Thread(p,"小C").start();}}class Person extends Thread{//表示苹果总数private int num = 50;public void run(){for (int i = 0; i < 50; i++) {if(num > 0){System.out.println(Thread.currentThread().getName() + "吃了编号为:" + num-- + "的苹果!");}}}}
方式三:可以使用实现Runnable接口的方式来实现(实现接口成功,可实现其功能!)
//方式三:可以使用实现Runnable接口的的方式来实现;public class EatAppleImpl {public static void main(String[] args) {//创建申请那个线程(同学),吃苹果Apple a = new Apple();//三个线程共享Apple中的成员变量资源(num资源)new Thread(a,"小A").start();new Thread(a,"小B").start();new Thread(a,"小C").start();}}class Apple implements Runnable{private int num = 50;public void run(){for (int i = 0; i < 50; i++) {if(num > 0){String threadName = Thread.currentThread().getName();//获取当前的线程,进而获取线程名称System.out.println(threadName + "吃了编号为:" + num-- + "的苹果!");}}}}
对应上述代码,出现这种结果情况:
小B吃了编号为:50的苹果!小A吃了编号为:49的苹果!小C吃了编号为:49的苹果!小A吃了编号为:48的苹果!小B吃了编号为:46的苹果!小C吃了编号为:47的苹果!
以及这种情况:
小A吃了编号为:3的苹果!小C吃了编号为:2的苹果!小C吃了编号为:1的苹果!小B吃了编号为:-1的苹果!小A吃了编号为:0的苹果!
这两种结果会导致多想访问统一资源的安全问题!
重点:继承方式和实现方式的区别:
继承方式:
1)Java中类是单继承的,如果继承了Thread类,该类就不能再有其他的直接父类;
2)从操作上分析,继承方式更加简单,获取线程名称简单!(操作简单);
3)从多线程共享同一资源上分析,继承Thread类方式一是不能实现资源的共享,但是方式二是可以实现的(本质上Thread类也实现类Runnable接口)
实现方式:
1)Java中类可以实现接口,此时该类还可以继承其他的类,并且还可以实现其他的接口(设计上更加优雅和优秀);
2)从操作上分析,实现方式稍微有点复杂,获取线程的名称也比较复杂,得使用Thread,currentThread()来获取当前的线程,进而获取线程的名称;
3)从多线程共享同一资源上分析,实现接口可以做到多个线程共享资源!(是否共享同一个资源);
4)默认的Thread.run()就是直接调用内部的Runabble接口,因此使用Runnable接口告诉线程该做什么,比较合理。
下一篇对应此例子,实现多线程访问共同资源的安全问题:http://blog.csdn.net/super_yc/article/details/73294203
- 线程的实例讲解
- Java 线程实例讲解综述
- Java 线程实例讲解综述
- Java 线程实例讲解综述
- Java 线程实例讲解综述
- Java 线程实例讲解综述
- Java线程实例讲解综述
- Java 线程实例讲解综述
- 线程的讲解
- java线程的讲解
- ListView的实例讲解
- Makefile的实例讲解
- Makefile的实例讲解
- WaitableTimer的实例讲解
- AIDL的实例讲解
- ps命令实例讲解 查看线程信息
- Java5中的线程池实例讲解
- Java5中的线程池实例讲解
- iOS-UITableView内容之重要属性
- java学习之一java基本知识
- java对象创建过程
- 成为一名Java高级工程师你需要学什么
- C# ActiveX开发打印机控件
- 线程的实例讲解
- 进程间交流信号灯
- 每日一学(五) Java内存分配浅析
- 我们前端是怎么找到工作的
- ubuntu 14.04 安装openjdk 8
- 2.10 本地化的菜单命令
- crt1.o, crti.o, crtbegin.o, crtend.o, crtn.o
- 淘淘商城系列——单点登录之用户注册
- 注册时间差计算