1)继承Thread,重写其的run方法
2)实现Runnable接口,重写run方法.
代码如下:
- package com.study;
- /**
- *
- * @ClassName: ThreadTest
- * @Description: 创建线程的两种方式
- * @author 我夕
- */
- public class ThreadTest {
- public static void main(String[] args) {
- System.out.println("当前线程的名字:"+Thread.currentThread().getName()+";线程ID:"+Thread.currentThread().getId());
- ThreadOne one=new ThreadOne();
- one.setName("ThreadOne");//为了便于调试,建议创建时给线程设个名称
- one.start();
- Thread two2=new Thread(new ThreadTwo());
- two2.setName("ThreadTwo");
- two2.start();
- }
- //继承Thread,覆盖父类run方法
- public static class ThreadOne extends Thread{
- @Override
- public void run() {
- // TODO Auto-generated method stub
- super.run();
- //do xx
- System.out.println("当前线程的名字:"+Thread.currentThread().getName()+";线程ID:"+Thread.currentThread().getId());
- }
- }
- //实现Runnable接口
- public static class ThreadTwo implements Runnable{
- @Override
- public void run() {
- // TODO Auto-generated method stub
- //do xx
- System.out.println("当前线程的名字:"+Thread.currentThread().getName()+";线程ID:"+Thread.currentThread().getId());
- }
- }
- }
总结:
创建线程的传统方式就上面两种(这里不考虑jdk1.5种线程并发库里的创建方式,后续会写到),但写的方式却是多种多样,希望初学者不要被其搞混掉
两种方式都可以创建线程,第一种方式创建比较简单,但由于java是单继承的缘故,创建出的Thread子类就无法在继承其他类;实现Runnable接口的方式可以将cpu、代码和数据分开,同时创建出的线程可以共享处理同一份资源。
记住:Thread类本身也实现了Runnable接口,因此Thread类及其子类的对象也可以作为target传递给新的线程对象。
三、两种创建线程方式的比较
采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标(target)对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
提示:在实际开发中,一般采用实现Runnable接口的方式来创建线程类,因为它具有更好的灵活性和可扩展性。
3)第三种方法是以匿名内部类的方式创建,
内部类也可以,不必匿名.
即可以在一个方法中创建线程,当 方法被调用时,线程即启动,这在编写一些简单线程应用时十分方便,如swing事件中处理 一个可能时间较长的任务,使用这种方法就不致于阻塞用户界面的操作。
public class ThreadTest {
//程序主方法
public static void main(String args[]){
ThreadTest tt = new ThreadTest();
for(int i=0;i<10;i++){
tt.strartMyThread(i);
}
}
/**
* 这个方法会启动一个匿名线程线程
*/
public void strartMyThread(int threadID) {
//要传入匿名线程内使用的参数必须定义为final型
final int id=threadID;
Runnable runner = new Runnable() {
public void run(){
int i=10;
boolean flag=true;
while(flag){
try{
Thread.sleep(3000);
//在匿名线程类调用类中的其它方法
otherMethod(id);
if(i>13){
flag=false;
}
}catch(Exception ef){}
}
}
};
//最后,启动这个内部线程
Thread t = new Thread(runner);
t.start();
}
//测试方法
private void otherMethod(int i){
System.out.println("可以直接调用类中的其它方法: "+i);
}
}
在程序中使用匿名内部类创建线程十分方便:在一个方法调用中就可以启动一个线程,而
且这个线程还可以直接调用类中的属性和方法;特别注意的是,在方法中启动匿名内部线程
时,如要向这个线程的 run 方法内传递参数,在创建方法中这个参数必须定义为 final 类型,
如上代码中的
//要传入匿名线程内使用的参数必须定义为final型
final int id=threadID;