Java多线程初学者指南(2):用Thread类创建线程

  Java 中创建线程有两种方法:使用Thread 类和使用Runnable 接口。在使用Runnable 接口时需要建立一个Thread 实例。因此,无论是通过Thread 类还是Runnable 接口建立线程,都必须建立Thread 类或它的子类的实例。Thread 类的构造方法被重载了八次,构造方法如下:
public  Thread( );
public  Thread(Runnable target);
public  Thread(String name);
public  Thread(Runnable target, String name);
public  Thread(ThreadGroup group, Runnable target);
public  Thread(ThreadGroup group, String name);
public  Thread(ThreadGroup group, Runnable target, String name);
public  Thread(ThreadGroup group, Runnable target, String name,  long  stackSize);
Runnable target
实现了Runnable 接口的类的实例。要注意的是Thread 类也实现了Runnable 接口,因此,从Thread 类继承的类的实例也可以作为target 传入这个构造方法。
String name
线程的名子。这个名子可以在建立Thread 实例后通过Thread 类的setName 方法设置。如果不设置线程的名子,线程就使用默认的线程名:Thread-N N 是线程建立的顺序,是一个不重复的正整数。
ThreadGroup group
当前建立的线程所属的线程组。如果不指定线程组,所有的线程都被加到一个默认的线程组中。关于线程组的细节将在后面的章节详细讨论。
long stackSize
    线程栈的大小,这个值一般是CPU 页面的整数倍。如x86 的页面大小是4KB 。在x86 平台下,默认的线程栈大小是12KB
一个普通的Java 类只要从Thread 类继承,就可以成为一个线程类。并可通过Thread 类的start 方法来执行线程代码。虽然Thread 类的子类可以直接实例化,但在子类中必须要覆盖Thread 类的run 方法才能真正运行线程的代码。下面的代码给出了一个使用Thread 类建立线程的例子:
   001    package  mythread;
  
002   
  
003    public   class  Thread1  extends  Thread
  
004   {
  
005        public   void  run()
  
006       {
  
007           System.out.println( this .getName());
  
008       }
  
009        public   static   void  main(String[] args)
  
010       {
  
011           System.out.println(Thread.currentThread().getName());
  
012           Thread1 thread1  =   new  Thread1();
  
013           Thread1 thread2  =   new  Thread1 ();
  
014           thread1.start();
  
015           thread2.start();
  
016       }
  
017   }

     上面的代码建立了两个线程:thread1和thread2。上述代码中的005至008行是Thread1类的run方法。当在014和015行调用start方法时,系统会自动调用run方法。在007行使用this.getName()输出了当前线程的名字,由于在建立线程时并未指定线程名,因此,所输出的线程名是系统的默认值,也就是Thread-n的形式。在011行输出了主线程的线程名。
    上面代码的运行结果如下:
main
Thread-
0
Thread-
1
从上面的输出结果可以看出,第一行输出的main 是主线程的名子。后面的Thread-1 Thread-2 分别是thread1 thread2 的输出结果。
注意: 任何一个 Java 程序都必须有一个主线程。一般这个主线程的名子为 main 。只有在程序中建立另外的线程,才能算是真正的多线程程序。也就是说,多线程程序必须拥有一个以上的线程。
    Thread 类有一个重载构造方法可以设置线程名。除了使用构造方法在建立线程时设置线程名,还可以使用Thread 类的setName 方法修改线程名。要想通过Thread 类的构造方法来设置线程名,必须在Thread 的子类中使用Thread 类的 public Thread(String name) 构造方法,因此,必须在Thread 的子类中也添加一个用于传入线程名的构造方法。下面的代码给出了一个设置线程名的例子:
   001    package  mythread;
  
002   
  
003    public   class  Thread2  extends  Thread
  
004   {
  
005        private  String who;
  
006   
  
007        public   void  run()
  
008       {
  
009           System.out.println(who  +   " : "   +   this .getName());
  
010       }
  
011        public  Thread2(String who)
  
012       {
  
013            super ();
  
014            this .who  =  who;
  
015       }
  
016        public  Thread2(String who, String name)
  
017       {
  
018            super (name);
  
019            this .who  =  who;
  
020       }
  
021        public   static   void  main(String[] args)
  
022       {
  
023           Thread2 thread1  =   new  Thread2 ( " thread1 " " MyThread1 " );
  
024           Thread2 thread2  =   new  Thread2 ( " thread2 " );
  
025           Thread2 thread3  =   new  Thread2 ( " thread3 " );
  
026           thread2.setName( " MyThread2 " );
  
027           thread1.start();
  
028           thread2.start();
  
029           thread3.start();
  
030       }
  
031   
在类中有两个构造方法:
011 行: public sample2_2(String who)
这个构造方法有一个参数:who 。这个参数用来标识当前建立的线程。在这个构造方法中仍然调用Thread 的默认构造方法public Thread( )
016 行: public sample2_2(String who, String name)
这个构造方法中的who 和第一个构造方法的who 的含义一样,而name 参数就是线程的名名。在这个构造方法中调用了Thread 类的public Thread(String name) 构造方法,也就是第018 行的super(name)
main 方法中建立了三个线程:thread1 thread2 thread3 。其中thread1 通过构造方法来设置线程名,thread2 通过setName 方法来修改线程名,thread3 未设置线程名。
    运行结果如下:
thread1:MyThread1
thread2:MyThread2
thread3:Thread-
1
从上面的输出结果可以看出,thread1 thread2 的线程名都已经修改了,而thread3 的线程名仍然为默认值:Thread-1 thread3 的线程名之所以不是Thread-2 ,而是Thread-1 ,这是因为在026 已经指定了thread2的Name,因此, 启动thread3 时就将thread3 的线程名设为Thread-1 因此就会得到上面的输出结果。
注意: 在调用 start 方法前后都可以使用 setName 设置线程名,但在调用 start 方法后使用 setName 修改线程名,会产生不确定性,也就是说可能在 run 方法执行完后才会执行 setName 。如果在 run 方法中要使用线程名,就会出现虽然调用了 setName 方法,但线程名却未修改的现象。
Thread 类的 start 方法不能多次调用,如不能调用两次 thread1.start() 方法。否则会抛出一个 IllegalThreadStateException 异常。
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值