实现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()方法实现。