线程与进程很相似,他们都是程序的一个顺序执行机构,但又有一些区别。进程是一个实体,每个进程都有自己独立的状态和自己的专用数据段。线程则共享数据,同一个程序中的所有线程只有一个数据段,线程间可能互相影响,比如数据访问的互斥和同步。
线程本身的数据通常只有寄存器数据和程序执行时的堆栈段,所以线程的切换比进程的负担要小。线程不能自动运行,必须跻身在某一进程中,由进程触发。一个进程可以有多个线程且进程间不共用线程。
实现多线程有两种方法,一是继承Thread类,二是实现Runnable接口。
继承Thread类创建线程时,首先要定义一个Thread类的子类,并在该子类中重写run()方法。run()方法是线程体,说明该线程的具体操作。需要创建线程时,只需创建该子类的对象在调用其start()方法即可。
实现Runnable接口创建线程必须重写该接口的run()方法(Runnable接口只有一个run()方法)。
由于Java是单继承语言,不直接支持多继承,如果一个类已经是其他类的子类,就不能在继承Thread方法使该类成为线程类,这时就要采用实现Runnable接口的方式。
两种方法创建的线程中具有相同目标对象的线程可以共享内存单元,但是实现Runnable接口的线程去创建目标对象的类可以是某个特定类的子类,因此实现Runnable接口创建线程比继承Thread类创建线程更灵活。
举几个小例子来看一下哈
继承Thread类实现的多线程:
class MyThread1 extends Thread{
private String name;
public MyThread1(String name){
this.name= name;
}
public void run(){
for(int i=0;i<15;i++){
System.out.println(this.name+"---->Is Running");
}
}
}
public class ThreadDemo01{
public static void main(String[] args){
Runnable r1 = new MyThread1("线程A");
Runnable r2 = new MyThread1("线程B");
Runnable r3 = new MyThread1("线程C");
Runnable r4 = new MyThread1("线程D");
Thread t1 = new Thread (r1);
Thread t2 = new Thread (r2);
Thread t3 = new Thread (r3);
Thread t4 = new Thread (r4);
t1.start();
t2.start();
t3.start();
t4.start();
//也可以这样写
/* MyThread mt1 = new MyThread("线程A");
MyThread mt2 = new MyThread("线程B");
MyThread mt3 = new MyThread("线程C");
MyThread mt4 = new MyThread("线程D");
mt1.start();
//同一线程不能连续启动,编译没错误,但运行错误
mt2.start();
mt3.start();
mt4.start();*/
}
}
0.0!!运行结果好长,就不截图了哈,可以自己试试。
实现Runnable接口的多线程(实现了共享资源):
class MyThread2 implements Runnable{
//定义十张票
private int ticket=10;
public void run(){
for(int i=0;i<500;i++){
if(this.ticket>0){
System.out.println("卖票-------"+(this.ticket--));
}
}
}
}
public class ThreadDemo02 {
public static void main(String[] args){
MyThread2 mt =new MyThread2();
//共享同一资源
Thread mt1 = new Thread(mt);
Thread mt2 = new Thread(mt);
Thread mt3 = new Thread(mt);
mt1.start();
mt2.start();
mt3.start();
}
}
运行结果: