创建线程有两种方法:
- 需要从Java.lang.Thread类派生一个新的线程类,重写它的run()方法;
- 实现Runnalbe接口,重载Runnalbe接口中的run()方法。
一、将类声明为Thread的子类。该子类应重写Thread 类的 run 方法(线程之间相互独立,不可共享资源)。接下来可以分配并启动该子类的实例。
例如,计算大于某一规定值的质数的线程可以写成:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}然后,下列代码会创建并启动一个线程:
PrimeThread p = new PrimeThread(143);
p.start();
代码示例:
class Demo_01 extends Thread{
private String name;
Demo_01(String name){
super(name);
//this.name = name;
}
public void run(){
for(int x = 0; x < 10; x++){
for (int y = 0; y < 7777777; y++){}
System.out.println("..."+"x="+x+"..."+Thread.currentThread().getName());
}
}
}
public class Test_01 {
public static void main(String[] args) {
Demo_01 d1 = new Demo_01("张三");
Demo_01 d2 = new Demo_01("lisi");
d1.start();
d2.start();
}
}
二、声明实现 Runnable 接口的类(实现Runable接口)。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。(可以线程之间相互独立,不可共享资源。也可以所有线程共享同一资源)
采用这种风格的同一个例子如下所示:
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}然后,下列代码会创建并启动一个线程:
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
代码示例:
//一、线程独立拥有资源,互不影响
class Demo_02 implements Runnable{
public void run(){
show();
}
private void show() {
for (int i = 0; i < 20; i++){
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}
public class Test_02 {
public static void main(String[] args) {
Demo_02 d1 = new Demo_02();
Demo_02 d2 = new Demo_02();
Thread t1 = new Thread(d1);
Thread t2 = new Thread(d2);
t1.start();
t2.start();
}
}
//二、线程共享资源
class Demo_02 implements Runnable{
private int i = 20;
public void run(){
show();
}
private void show() {
while(i > 0){
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}
public class Test_02 {
public static void main(String[] args) {
Demo_02 d = new Demo_02();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t2.start();
}
}
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。
上述内容详见Java JDK API 文档
两种创建方式的区别
在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.这样,如果创建自定义线程类的时候是通过扩展 Thread类的方法来实现的,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能。因此,如果自定义类必须扩展其他的类,那么就可以使用实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性。
还有一点最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享.
通过扩展Thread类来创建多线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。
通过实现Runnable接口来创建多线程,程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。