使用多线程在实际的项目开发过程中是十分常见的。学好多线程可以更好的帮助我们开发项目。下面来初步了解一下
说到Java多线程,我们先来学习一下Thread这个类。
Thread这个类代表一个线程。使用它很方便,只需要new一个对象出来调用start方法就可以启动一个新的线程。
使用Thread需要注意以下几点问题
- 调用start方法启动线程。一个线程只能被启动一次,再一次启动会抛出异常 IllegalThreadStateException。也就说start方法只能调用一次。
- 如果在Thread构造函数传入Runnable对象,没有覆写Thread的run方法,那么执行Runnable的run方法。覆写Thread的run方法,那么执行Thread的run方法因为Thread是Runnable子类,覆盖了Runnable的run方法。
下面看一个实例
package first;
import java.security.AccessControlContext;
public class Demo01 {
public static void main(String[] args) {
new Thread(new LightOff()).start();
}
}
class LightOff implements Runnable {
protected int countdown = 10;
private static int taskcount = 0;
private final int id = taskcount++;
public LightOff() {
}
public LightOff(int countdown) {
this.countdown = countdown;
}
public String status() {
return "#" + id + "(" + (countdown > 0 ? countdown : 9) + ")";
}
public void run() {
while (countdown-- > 0) {
System.out.println(status() + Thread.currentThread().getName());
// Thread.yield();
}
}
}
上面示例代码就是一个简单额创建新的线程的例子。我们
来看一下start方法的具体实现
/*
* Thread的start方法为线程的执行做一些初始操作
* 阅读Thread源码可以发现start方法是同步方法,在start方法主要完成一下工作
* 1 判断线程是否已经被启动 threadStatus=0表示还没被启动,threadStatus!=0表示已经被启动,
* 如果线程被启动,再一次启动该线程会抛出线程状态不合法异常
* 2 把线程对象添加到线程组里面,通知线程组这个线程将要启动
* 3 调用start0本地方法来正式启动线程
*
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) {
}
}
}
private native void start0();
* 看一下Thread的 public Thread(Runnable target)的实现
*
* public Thread(Runnable target) {
init(null,target,"Thread-"+nextThreadNum(), 0);}
接受一个Runnable对象的构造函数会调用下面私有构造函数
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
这个方法会做一些权限判断,并且设置线程的优先级,id。
init(g, target, name, stackSize, null);
不管使用哪个构造函数来创建Thread对象,实际上都是再底层调用
private void init(ThreadGroup g, Runnable target, String name,longstackSize,AccessControlContextacc)
*/