上一篇我们提到到底该如何选择多线程使用哪一个?
我们通过一个例子来说明他们的不同:
Thread 代码如下:
package com.game.test;
public class TicketThread extends Thread{
private int ticketCount=5;
public void run(){
for(int i=0;i<7;i++){
if(this.ticketCount>0){
System.out.println("剩余的数量====>"+ticketCount--);
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//模拟3个线程取票
TicketThread t1=new TicketThread();
TicketThread t2=new TicketThread();
TicketThread t3=new TicketThread();
t1.start();
t2.start();
t3.start();
}
}
[输出结果]
剩余的数量====>5
剩余的数量====>4
剩余的数量====>3
剩余的数量====>2
剩余的数量====>1
剩余的数量====>5
剩余的数量====>4
剩余的数量====>5
剩余的数量====>4
剩余的数量====>3
剩余的数量====>3
剩余的数量====>2
剩余的数量====>1
剩余的数量====>2
剩余的数量====>1
如果这个是一个买票系统的话, 如果ticket是车票数量的话,说明并没有实现资源共享.
我们换为runnable 代码如下:
package com.game.test;
public class TicketRunnable implements Runnable{
private int ticket=5;
/**
* @param args
*/
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<20;i++){
if(this.ticket>0){
System.out.println("当前线程"+Thread.currentThread().getName()+"正在卖票"+ticket--);
}
}
}
public static void main(String[] args) {
TicketRunnable tr=new TicketRunnable();
new Thread(tr,"1号窗台").start();
new Thread(tr,"2号窗台").start();
new Thread(tr,"3号窗台").start();
}
}
当前线程2号窗台正在卖票4
当前线程2号窗台正在卖票2
当前线程2号窗台正在卖票1
当前线程3号窗台正在卖票3
当前线程1号窗台正在卖票5
总结一下吧:
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
所以换是建议大家实现接口的方式操作线程.
另外如果没有指定线程的名字的话,系统会自动提供名字 例如:
package com.game.test;
public class GetThreadName implements Runnable{
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GetThreadName gr=new GetThreadName();
new Thread(gr,"A").start();
new Thread(gr,"B").start();
new Thread(gr).start();
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName());
}
}
}
[输出结果]
B
B
B
Thread-0
Thread-0
Thread-0
A
A
A
其实我们的main方法也是一个线程.在java中所有的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到系统的CPU资源.
在java中,我们每次程序运行至少启动2个线程.一个是main线程,一个是垃圾收集线程.
如何判断线程是否已经启动呢?
package com.game.test;
public class GetThreadName implements Runnable{
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GetThreadName gr=new GetThreadName();
Thread t1=new Thread(gr);
System.out.println("线程启动之前========>"+t1.isAlive());
t1.start();
System.out.println("线程启动之后========>"+t1.isAlive());
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName());
}
}
}
[结果如下]
线程启动之前========>false
线程启动之后========>true
Thread-0
Thread-0
Thread-0
今天就先介绍到这里,后面我们在探讨线程.