Thread类是一个支持多线程的功能类,只要有一个子类它就可以实现多线程。
除此之外,所有程序的起点是main方法,所有线程也有一个自己的起点,run方法,多线程的每个主体类之中都必须覆写Thread类中所提供的run()方法。
public void run()
这个方法没有返回值,表明了线程一旦开始无法停止。
下面看一个示例:
package TestDemo;
class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name=name;
}
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println(this.name+"==>"+i);
}
}
}
public class TestDemo{
public static void main(String[] args) {
MyThread thread1=new MyThread("ThreadA");
MyThread thread2=new MyThread("ThreadB");
MyThread thread3=new MyThread("ThreadC");
thread1.run();
thread2.run();
thread3.run();
}
}
本线程类的功能是实现一个循环输出操作,我们的线程和进程一样,都必须轮流抢占资源。多线程的执行应该是多个线程并发执行。而我们上面的结果是:
image.png
顺序执行,显然与初衷不符。因此并没有真正启动多线程,真正启动多线程的是Thread类种的start()方法。
public void start();
但是调用此方法执行的方法体是run()方法定义的。我们将方法改为start()方法。
package TestDemo;
class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name=name;
}
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println(this.name+"==>"+i);
}
}
}
public class TestDemo{
public static void main(String[] args) {
MyThread thread1=new MyThread("ThreadA");
MyThread thread2=new MyThread("ThreadB");
MyThread thread3=new MyThread("ThreadC");
thread1.start();
thread2.start();
thread3.start();
}
}
image.png
的确实现了并发执行的真-多线程。
疑问?为什么多线程启动不是调用run()而是调用start()方法?
我们打开jdk的安装路径,查看以下src压缩包中,Thread类中start()方法的源码:
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
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();
首先发现start方法中throw了一个IllegalThreadStateException() ,此方法没有try catch处理,也没有在start()方法上添加throws继续向调用start方法的上层抛出,这是一个RuntimeException,属于选择性异常,如果一个线程重复启动,就会抛出这个异常。
此外在start()方法中,调用了一个start0方法,使用native进行声明。
这里就引出了一个,Java中有一门技术叫JNI,这们技术能:使用Java调用本机操作系统提供的函数。但是这样的技术有一个缺点,不能够离开特定的操作系统。
如果想要线程能够执行,需要操作系统来进行资源分配,需要由JVM负责根据不同的操作系统而实现。(JVM跨平台跨操作系统调用资源,实现多线程 因而start0方法在不同的操作系统上有不同的体现)
网友评论