在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类建设线程的例子:

复制代码 代码如下:

package mythread; public class Thread1 extends Thread{public void run(){System.out.println(this.getName());}public static void main(String[] args){System.out.println(Thread.currentThread().getName());Thread1 thread1 = new Thread1();Thread1 thread2 = new Thread1 ();thread1.start();thread2.start();}}

下面的代码建设了两个线程:thread1和thread2。上述代码中的005至行是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的子类中也增加一个用于传入线程名的构造方法。上面的代码给出了一个设置线程名的例子:

复制代码 代码如下:

package mythread;public class Thread2 extends Thread{private String who;public void run(){System.out.println(who + ":" + this.getName());}public Thread2(String who){super();this.who = who;}public Thread2(String who, String name){super(name);this.who = who;}public static void main(String[] args){Thread2 thread1 = new Thread2 ("thread1", "MyThread1");Thread2 thread2 = new Thread2 ("thread2");Thread2 thread3 = new Thread2 ("thread3");thread2.setName("MyThread2");thread1.start();thread2.start();thread3.start();}

在类中有两个构造方法:
第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:MyThread1thread2:MyThread2thread3: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异样。