实现java的多线程操作之继承Thread父类

在java中,对于多线程实现一定要有一个线程的主类,而这个线程的主类往往是需要操作一些资源。但是对于这个多线程主类的实现是有一定要求的:
1.继承Thread父类;
2.实现Runnable接口(Callable接口)

1.1 继承Thread类实现多线程
在java.lang包中存在有Thread类,子类在继承Thread类之后需要覆写Thread中的run()方法,那么这个方法就属于线程的主方法。定义:public void run(){}

范例:实现线程的主体类

class MyThread extends Thread{//表示实现多线程
    private String name;
    public MyThread(String name){//线程名称
        this.name = name;
    }
    @Override
    public void run() {//覆写run(),线程的主方法
        for(int i = 0;i < 10;i++){
            System.out.println(this.name + ",i = " + i);
        }
    }
}

在线程的主类之中,只是将内容输出10次。但是需要注意的是:所有多线程的执行一定是并发完成的,即:在同一个时间段上会有多个线程交替执行所以为了达到这样的目的,绝对不能直接去调用run(),而是应该调用Thread类中的start()方法启动多线程:public void start(){}

范例:启动多线程

package day1;

class MyThread extends Thread{//表示实现多线程
    private String name;
    public MyThread(String name){//线程名称
        this.name = name;
    }
    @Override
    public void run() {//覆写run(),线程的主方法
        for(int i = 0;i < 10;i++){
            System.out.println(this.name + ",i = " + i);
        }
    }
}
public class TestDemo {
    public static void main(String[] args) {
        MyThread m1 = new MyThread("thread1");
        MyThread m2 = new MyThread("thread2");
        MyThread m3 = new MyThread("thread3");
        MyThread m4 = new MyThread("thread4");
        m1.start();
        m2.start();
        m3.start();
        m4.start();
    }
}
thread1,i = 0
thread3,i = 0
thread3,i = 1
thread2,i = 0
thread3,i = 2
thread3,i = 3
thread1,i = 1
threa4,i = 0
thread1,i = 2
thread3,i = 4
thread2,i = 1
thread3,i = 5
thread1,i = 3
threa4,i = 1
thread1,i = 4
thread3,i = 6
thread2,i = 2
thread3,i = 7
thread1,i = 5
threa4,i = 2
thread1,i = 6
thread3,i = 8
thread2,i = 3
thread2,i = 4
thread3,i = 9
thread1,i = 7
thread1,i = 8
thread1,i = 9
threa4,i = 3
threa4,i = 4
threa4,i = 5
threa4,i = 6
threa4,i = 7
thread2,i = 5
thread2,i = 6
thread2,i = 7
thread2,i = 8
thread2,i = 9
threa4,i = 8
threa4,i = 9

所有线程都属于交替执行,本身是没有固定的执行顺序的

如果是用的run()启动,范例如下:

thread1,i = 0
thread1,i = 1
thread1,i = 2
thread1,i = 3
thread1,i = 4
thread1,i = 5
thread1,i = 6
thread1,i = 7
thread1,i = 8
thread1,i = 9
thread2,i = 0
thread2,i = 1
thread2,i = 2
thread2,i = 3
thread2,i = 4
thread2,i = 5
thread2,i = 6
thread2,i = 7
thread2,i = 8
thread2,i = 9
thread3,i = 0
thread3,i = 1
thread3,i = 2
thread3,i = 3
thread3,i = 4
thread3,i = 5
thread3,i = 6
thread3,i = 7
thread3,i = 8
thread3,i = 9
thread4,i = 0
thread4,i = 1
thread4,i = 2
thread4,i = 3
thread4,i = 4
thread4,i = 5
thread4,i = 6
thread4,i = 7
thread4,i = 8
thread4,i = 9

所有线程都属于依次执行,本身是有固定的执行顺序的

思考:为什么现在启动多线程不使用run(),而非要用start()?

start()源码:
public synchronized void start() {
	if (threadStatus != 0)
		throw new IllegalThreadStateException();
	group.add(this);
	boolean started = false;
	try {
		start0();
		started = true;
	} finally {
		try {
			if (!started) {
				group.threadStartFailed(this);
			}
		} catch (Throwable ignore) {
			/* do nothing. If start0 threw a Throwable then
			  it will be passed up the call stack */
		}
	}
}
private native void start0();

现在代码中首先发现,方法中出现抛出一个异常“IllegalThreadStateException()”,但是整个方法中没有使用throws声明,没有使用try…catch捕获处理,而之所以会出现这样的情况,是因为此异常属于RuntimaException的子类。

java.lang.Object
	java.lang.Throwable
		java.lang.Exception
			java.lang.RuntimeException
				java.lang.IllegalArgumentException
					java.lang.IllegalThreadStateException

此异常是指一个线程已经调用了start()后有重复执行了start()方法所造成的的问题。
在调用start()方法里面发现会调用start0()方法,而start0()方法上使用了native关键字定义,这个关键字指的是调用那个本机的操作系统函数。

由于线程的启动需要牵扯到操作系统中资源的分配问题,所以具体的线程的启动应该要根据不同的操作系统有不同的实现,而JVM相当于系统中定义的start0()方法来根据不同的操作系统进行改方法的实现,这样在多线程的层次上start0()方法名称不改变。而不同的操作系统上有不同的实现。

结论:只有Thread类的start()方法才能够进行操作系统资源的分配,所以启动多线程的方式永远就是调用Thread类中的start()方法实现。