1、Java中线程的创建有两种方式:
通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中;
通过实现Runnable接口,实例化Thread类;
(1)、继承Thread类
/**
* 继承Thread类,我们相当于拿出三件事:即三个卖票5张的任务分别分给三个窗口,
* 他们各做各的事各卖各的票各完成各的任务,因为MyThread继承Thread类,
* 所以在new MyThread的时候在创建三个对象的同时创建了三个线程;
* @author lmb
*
*/
public class MyThread extends Thread{
private int ticket = 5;
private String name;
public MyThread(String name){
this.name = name;
}
@Override
public void run() {
for(int i = 0 ;i < 100 ; i++) {
if (this.ticket > 0) {
System.out.println(this.name + "卖票 : " + ticket--);
}
}
}
public static void main(String[] args) {
//new MyThread()相当于创建一个任务和一个线程,总共三个任务三个线程
MyThread t1 = new MyThread("一号窗口");
MyThread t2 = new MyThread("二号窗口");
MyThread t3 = new MyThread("三号窗口");
t1.start();
t2.start();
t3.start();
}
/*某次运行结果:
二号窗口卖票 : 5
二号窗口卖票 : 4
二号窗口卖票 : 3
二号窗口卖票 : 2
二号窗口卖票 : 1
一号窗口卖票 : 5
一号窗口卖票 : 4
一号窗口卖票 : 3
一号窗口卖票 : 2
一号窗口卖票 : 1
三号窗口卖票 : 5
三号窗口卖票 : 4
三号窗口卖票 : 3
三号窗口卖票 : 2
三号窗口卖票 : 1
*/
}
(2)、实现Runnable接口
/**
* 实现Runnable接口, 相当于是拿出一个卖票5张的任务给三个人去共同完成,
* new MyThread2相当于创建一个任务,然后实例化三个Thread,创建三个线程即安排三个窗口去执行。
* @author lmb
*
*/
public class MyThread2 implements Runnable{
private int ticket = 5;
@Override
public void run() {
for (int i = 0 ;i < 100; i ++) {
if (this.ticket > 0) {
System.out.println(Thread.currentThread().getName() + "卖票 : " + ticket--);
}
}
}
public static void main(String[] args) {
MyThread2 t = new MyThread2();//一个任务
//三个线程
Thread t1 = new Thread(t, "一号窗口");
Thread t2 = new Thread(t, "二号窗口");
Thread t3 = new Thread(t, "三号窗口");
t1.start();
t2.start();
t3.start();
}
/*某次运行结果:
一号窗口卖票 : 5
二号窗口卖票 : 5
三号窗口卖票 : 4
三号窗口卖票 : 1
二号窗口卖票 : 2
一号窗口卖票 : 3
*/
}
2、 Runnable接口和Thread之间的联系:
查看JDK源码中Thread的实现我们发现Thread类也是Runnable接口的子类。
public class Thread extends Object implements Runnable
3、两种实现方式的区别和联系:
在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:
避免单继承的局限,一个类可以实现多个接口。
适合于资源的共享(多个线程实现单个任务的资源)
4、run()方法和start()方法
public class ThreadRunableTest extends Thread {
private int ticket = 5;
private String name;
public ThreadRunableTest(String name){
this.name = name;
}
public void run() {
for(int i=0;i<20;i++){
if(this.ticket>0){
System.out.println(this.name + " 卖票:ticket="+this.ticket--);
}
}
}
public static void main(String[] args) {
//***************单任务**********************
ThreadRunableTest th = new ThreadRunableTest("买票窗口");
// th.run();
System.out.println("******************************");
// th.start();
/*单线程单任务看不出区别,某次运行结果均如下:
* 买票窗口 卖票:ticket=5
买票窗口 卖票:ticket=4
买票窗口 卖票:ticket=3
买票窗口 卖票:ticket=2
买票窗口 卖票:ticket=1
*/
//******************多任务*******************
ThreadRunableTest t11 = new ThreadRunableTest("一号窗口");
ThreadRunableTest t22 = new ThreadRunableTest("二号窗口");
ThreadRunableTest t33 = new ThreadRunableTest("三号窗口");
//***********三个线程执行三个任务顺序执行*************
t11.run();
t22.run();
t33.run();
/*某次结果
* 一号窗口 卖票:ticket=5
一号窗口 卖票:ticket=4
一号窗口 卖票:ticket=3
一号窗口 卖票:ticket=2
一号窗口 卖票:ticket=1
二号窗口 卖票:ticket=5
二号窗口 卖票:ticket=4
二号窗口 卖票:ticket=3
二号窗口 卖票:ticket=2
二号窗口 卖票:ticket=1
三号窗口 卖票:ticket=5
三号窗口 卖票:ticket=4
三号窗口 卖票:ticket=3
三号窗口 卖票:ticket=2
三号窗口 卖票:ticket=1
*/
System.out.println("**************************************************");
//***********三个线程执行三个任务交互执行*************
// t11.start();
// t22.start();
// t33.start();
/*某次结果
二号窗口 卖票:ticket=5
一号窗口 卖票:ticket=5
二号窗口 卖票:ticket=4
一号窗口 卖票:ticket=4
三号窗口 卖票:ticket=5
一号窗口 卖票:ticket=3
二号窗口 卖票:ticket=3
一号窗口 卖票:ticket=2
三号窗口 卖票:ticket=4
一号窗口 卖票:ticket=1
二号窗口 卖票:ticket=2
二号窗口 卖票:ticket=1
三号窗口 卖票:ticket=3
三号窗口 卖票:ticket=2
三号窗口 卖票:ticket=1
*/
}
}
总结:
从上面的方法我们可以看出: Runable只有run()方法,Thread既有run()方法,又有start()方法。 run()方法执行任务是顺序执行,一个任务完成之后在进行下一个; start()方法执行任务可以实现多线程任务的交互执行。