1.线程:线程就是进程基础上的一个划分;
一个进程就是一个程序,在一个程序上可以同时运行多个子程序,则这些子程序称为线程;
2.java的线程可以通过继承java.lang.Thread类来实现的;
多线程的实现需要操作系统的支持;
如果要执行一个线程要调用start()方法;
通过start()--》调用的是子类的run()方法;
class TestThread extends Thread{
public void run(){
}
}
每个线程都是通过某个特定Thread对象对应的方法run()来完成其操作的,
方法run()称为线程体;
java.lang 为程序默认的导入包,所以不用import导入该包了;
一个类只要继承了Thread类,则表示此类实现了多线程;
//编写一个类继承Thread类
class ThreadDemo extends Thread{
//因为多线程,需要一个程序的主体,就是run方法(需要覆写该方法)
//子类要覆写Thread类中的run方法
private String info;
public ThreadDemo(String info){
this.info=info;
}
public void run(){
for(int i=0;i<10;i++){
System.out.println(this.info+":i="+i);
}
}
}
public class Demo{
//如果是一个多线程应该是交替执行的;
public static void main(String args[]){
ThreadDemo d1=new ThreadDemo("线程1");
ThreadDemo d2=new ThreadDemo("线程2");
ThreadDemo d3=new ThreadDemo("线程3");
d1.start();
d2.start();
d3.start();
}
}
3.通过实现Runnable接口,实现多继承;
一个类只能继承一个父类,如果一个类继承了一个父类,怎就不能再继承
Thread类了,所以这是接口就出现了;
但是Thread类提供了专门启动线程的操作---start()方法,我们可以直接使用,
但是Runnable没有生命start();
注意:Thread类也实现了Runnable接口;
//编写一个类实现Runnable接口
class ThreadDemo implements Runnable{
//因为多线程,需要一个程序的主体,就是run方法(需要覆写该方法)
//子类要覆写Thread类中的run方法
private String info;
public ThreadDemo(String info){
this.info=info;
}
public void run(){
for(int i=0;i<10;i++){
System.out.println(this.info+":i="+i);
}
}
}
public class Demo{
//因为实现的是Runnable接口,所以需要通过Thread类启动多线程
public static void main(String args[]){
ThreadDemo d1=new ThreadDemo("线程1");
ThreadDemo d2=new ThreadDemo("线程2");
ThreadDemo d3=new ThreadDemo("线程3");
//因为是继承的接口,接口中时没有方法体的,所以该接口中没有start这个方法的
//但是Thread类中很好的构造方法,public Thread(Runnable r)
Thread t1=new Thread(d1);
Thread t2=new Thread(d2);
Thread t3=new Thread(d3);
t1.start();
t2.start();
t3.start();
}
}
4.既然Runnable 和Thread 类都可以实现多线程,那么改选谁呢?
实现接口,解决单继承局限;
Runnable接口和Thread的关系:
Thread 类也实现了Runnable接口;
特点:继承Thread类 多线程之间不能实现资源的共享,而实现了Runnable接口之后可以实现多个线程
之间资源的共享;
原因:原因就在于Thread类有start()方法,而Runnable是接口,没有start()---接口中不能用方法体的存在;
因为Thread类有start方法,继承Thread类的子类 被new时都是一个单独的线程,而线程都用自己内部的资源,
这样每个单独的线程start时资源就不能共享,自己执行自己的;
而实现Runnable的子类就不同了,因为接口没有start方法,所以子类也没有该方法,该子类的对象只能被当成
资源提供给Thread类---new Thread(Runnable的实现类),这样不管new几次,都是公用的这个(Runnable的实现类),
实现了资源的共享;
举例: 火车票---》多个售票点,一共10张票让多个多个售票点卖;
//继承Thread类不能实现多线程之间资源的共享;
class Demo1 extends Thread{
private int ticket=10;
public void run(){
while(this.ticket>0){
System.out.println("卖票:"+this.ticket--);
}
}
public class Demo{
public static void main(){
//准备四个售票点
Demo1 d1=new Demo();
Demo1 d2=new Demo();
Demo1 d3=new Demo();
Demo1 d4=new Demo();
d1.start();
d2.start();
d3.start();
d4.start();
}
}
//实现Runnable 接口可以实现资源的共享
class Demo1 implements Runnable{
private int ticket=10;
public void run(){
while(this.ticket>0){
System.out.println("卖票:"+this.ticket--);
}
}
public class Demo{
public static void main(){
//四个售票点控制同一资源:10张票
Demo1 d=new Demo();
thread t1=new Thread(d);
thread t2=new Thread(d);
thread t3=new Thread(d);
thread t4=new Thread(d);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
5.Thread 类与Runnable 接口
用Thread继承而来的线程,一个线程对象只能启动一次,即只能调用一次start方法;
实现Runnable 接口相对于 继承Thread类来说,有如下显著好处:
适合多个相干的同程序代码的线程去处理同一资源;
可以避免由于java单继承特性带来的局限性;
有利于程序的健壮性,代码能够被多个线程共享;