由于多线程的使用涉及的比较多,就以两篇文章来进行记录了。
目录
进程与线程
1、简介
程序是计算机指令的集合,而进程就是一个运行中的程序,它指的是从代码加载,执行到执行结束这样一个完整的过程。而每个进程都是占用不同的内存空间。
线程则是进程中某个单一的顺序的控制流,也被称为轻量进程,它被操作系统调度,并在处理器或在内核上运行。一个进程都有一个主线程,一个进程也可以由多个线程组成,每条线程并行执行不同的任务,这多个线程共享一个内存空间。
2、多线程的优点
(1)、多线程技术使程序响应更快
(2)、当前没有处理任务时可以将cpu处理时间让给其他任务
(3)、需要使用大量cpu处理时间的任务可以定期将处理时间让给其他任务
(4)、可以随时停止任务
(5)、可以通过设置任务的优先级来优先处理任务
3、实现多线程的两种方法
两种方法都以售卖票为例
(1)、继承Thread
优点:编写简单。如果需要访问当前线程,无须使用Thread.currentThread()方法,直接使用this,即可获得当前线程
缺点:因为线程类已经继承了Thread类,所以不能再继承其他父类
具体步骤:
1.创建Thread子类;
2.重写Thread类中的方法;
3.创建Thread子类对象,即创建一个线程对象;
4.调用线程对象的start()方法启动线程,之后系统会自动调用重写的run()方法中的具体实现。
代码实例:
package Study;
public class Exp03 extends Thread{
int ticket=6;
//重写Thread类的run()方法
public void run(){
//持续卖票。一直到剩余票数为0
while(this.ticket>=0){
System.out.println(this.getName()+"卖票-->"+(this.ticket--));
//对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
}
}
public static void main(String[] args){
Exp03 thread1=new Exp03();
Exp03 thread2=new Exp03();
thread1.setName("窗口1");
thread2.setName("窗口2");
thread1.start(); //线程运行
thread2.start();
}
}
输出结果
需要注意的是,例子中创建了2个线程并允许,多次运行的输出结果可能不一样。因为线程是通过线程调度来执行的,就是很多线程处理就绪状态,但实际只有一个线程在运行。因此操作系统会在一个线程空闲时撤下这个线程,改让其他线程来执行,即线程调度。
如果需要线程按照程序调用顺序来执行,必须要在执行前来判断前面的线程是否已经终止。这会在下一篇博文讲到的线程同步中出现
(2)、实现Runnable接口
优点:线程类只是实现了Runnable接口,还可以继承其他类。可以多个线程共享同一个目标对象,即非常适合多个相同线程来处理同一份资源的情况。
缺点:获取当前线程,必须使用Thread.currentThread()方法
具体步骤
1.定义实现Runnable接口的类,实现run()方法;
2.创建Runnable对象作为Thread类的target参数来创建Thread对象(实际的线程对象);
3.调用start()方法启动线程。
代码实例(2个实例,实例2利用该方法的优点对实例1进行修改):
实例1:
package Study;
public class Exp03 implements Runnable{
int ticket=6;
//重写Thread类的run()方法
public void run(){
//持续卖票。一直到剩余票数为0
while(this.ticket>=0){
System.out.println(Thread.currentThread().getName()+"卖票-->"+(this.ticket--));
//对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
}
}
public static void main(String[] args){
Exp03 t1=new Exp03(); //创建线程类对象
Exp03 t2=new Exp03();
Thread thread1=new Thread(t1); //创建线程
Thread thread2=new Thread(t2);
thread1.setName("窗口1"); //给线程命名
thread2.setName("窗口2");
thread1.start(); //线程运行
thread2.start();
}
}
输出结果
利用Runnable的优点,对实例1进行修改,实现多个线程处理同一个资源
实例2:
package Study;
public class Exp03 implements Runnable{
int ticket=6;
//重写Thread类的run()方法
public void run(){
//持续卖票。一直到剩余票数为0
while(this.ticket>=0){
System.out.println(Thread.currentThread().getName()+"卖票-->"+(this.ticket--));
//对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
}
}
public static void main(String[] args){
Exp03 t1=new Exp03(); //创建线程类对象
Thread thread1=new Thread(t1); //创建线程
Thread thread2=new Thread(t1);
thread1.setName("窗口1"); //给线程命名
thread2.setName("窗口2");
thread1.start(); //线程运行
thread2.start();
}
}
输出结果:
从输出结果可以看出,2个窗口同时在对一个对象t1的6张票进行销售,因此2个窗口总共卖出6张票,而不是实例1的12张票。
因此在用多线程处理共用资源的时候非常适合采用Runnable接口的方法