1.线程与进程
进程相当于动态的程序,是运行中的程序。而线程是比进程更小的单位,Java的多线程是实现并发机制的一种有效手段。进程在运行的时候可以同时执行多个小的程序单元,这些程序单元就叫做线程。
2.线程的实现
1)继承Thread类
1.1继承Thread类后必须重写run方法
public class MyThread extends Thread {
private int count;
/*
* (non-Javadoc)
*
* @see java.lang.Thread#run() 重写run方法
*/
public void run() {
while (true) {
System.out.println(count++);
}
}
}
1.2线程的启动
public class ThreadTest {
public static void main(String[] args) {
//实例化对象
MyThread mt = new MyThread();
//启动线程
mt.start();
}
}
注意:线程的启动不能直接调用run方法,只能通过start方法来启动。
2)实现Runnable接口
2.1实现Runnable接口
public class MyThread implements Runnable {
private int count;
public void run() {
while (true) {
System.out.println(count++);
}
}
}
2.2启动线程
public class ThreadTest {
public static void main(String[] args) {
//实例化对象
MyThread mt = new MyThread();
//启动线程
new Thread(mt).start();
}
}
注意:由于Runnable接口中没有start方法,所以利用Runnable接口来实现的线程的调用需要实例化一个Thread类的对象来接受线程类,再调用start方法启动线程。
以上两种方式不管是哪种都只能调用一次start方法
3.实现Runnable接口和继承Thread类的区别
虽然以上两种方法都可以实现线程,但是两种方法存在较大的区别,我们先看一段代码(火车售票系统)
public class MyThread extends Thread {
private int ticket = 5;
public void run() {
while (true) {
if (ticket > 0) {
System.out.println("正在售票" + ticket--);
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
//启动线程
new Thread().start();
new Thread().start();
new Thread().start();
}
}
运行结果:
正在售票5
正在售票4
正在售票5
正在售票5
正在售票4
正在售票3
正在售票3
正在售票4
正在售票3
正在售票2
正在售票2
正在售票2
正在售票1
正在售票1
正在售票1
上面这段代码启动了三个线程,三个线程分别售卖5张票,这与实际情况不符。我们希望三个线程同时售卖5张票。我们再来看一段代码
public class MyThread implements Runnable {
private int ticket = 5;
public void run() {
while (true) {
if (ticket > 0) {
//输出正在运行的线程名字以及剩余票数
System.out.println(Thread.currentThread().getName()+"正在售票" + ticket--);
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
MyThread mt=new MyThread();
//启动线程
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
}
运行结果:
正在售票5
正在售票4
正在售票3
正在售票2
正在售票1
以上代码同样创建了三个线程,但是每个线程调用的都是同一个对象mt中的run方法,访问的是同一个变量,共享资源,满足我们的需求。
4.Runnable接口的优点
我们在实际操作中更常使用Runnable接口来实现线程。原因在于;
1.可以共享资源
2.避免了单一继承的限制
3.有利于程序的健壮性,多个线程共享一段代码,操作同一个数据,数据与代码是独立的。