线程,又称为轻量级进程,是程序执行过程中的最小的单位。
JAVA中线程实现
1.是通过继承JAVA.Lang包里面的Thread类,重写里面的run方法
例如:
class MyThread extends Thread{
private String name;
public MyThread(String name) {
this.name = name ;
}
public void run(){
for(int i=0;i<5;i++)
System.out.println(this.name+"----"+i);
}
}
public class Hello{
public static void main(String []args){
MyThread t1 = new MyThread("线程1");
MyThread t2 = new MyThread("线程2");
MyThread t3 = new MyThread("线程3");
t1.start();
t2.start();
t3.start();
}
}
输出:
线程1----0
线程1----1
线程1----2
线程1----3
线程1----4
线程3----0
线程2----0
线程3----1
线程2----1
线程2----2
线程2----3
线程3----2
线程3----3
线程3----4
线程2----4
通过查看Thread的源码发现
Thread继承了Runnable接口。
**
2.通过实现Runnable接口来实现线程(实际运用更多)
Runnable实现线程没有返回值
**
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Runnable是一个函数式接口,里面只包含一个run方法,重写了run方法之后即可使用线程
**
但是线程的开始只能通过Thread.start()方法
**
Thread类里面有一个构造器
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
即可通过Runnable对象来构造Thread对象,再通过start方法来运行Runnable里面的run方法。
例如:
public class Hello{
public static void main(String []args){
//由于是函数式接口,可以采用匿名类,还可以采用Lambda表达式
Runnable r = () ->{
for(int i =0;i<5;i++) {
System.out.println(Thread.currentThread()+"-----"+i);
}
};
Runnable s = () ->{
for(int i =0;i<5;i++) {
System.out.println(Thread.currentThread()+"-----"+i);
}
};
new Thread(r).start();
new Thread(s).start();
}
}
输出
Thread[Thread-0,5,main]-----0
Thread[Thread-0,5,main]-----1
Thread[Thread-1,5,main]-----0
Thread[Thread-0,5,main]-----2
Thread[Thread-0,5,main]-----3
Thread[Thread-0,5,main]-----4
Thread[Thread-1,5,main]-----1
Thread[Thread-1,5,main]-----2
Thread[Thread-1,5,main]-----3
Thread[Thread-1,5,main]-----4
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 */
}
}
}
调用这个方法会导致此线程开始执行; Java虚拟机调用此线程的运行方法。
结果是两个线程同时运行:当前线程(从调用返回到start方法)和另一个线程(执行它的运行方法)。
线程的几种状态:
线程创建之后调用start方法,然后就进入就绪状态等待资源分配系统调用
线程运行过程中可能会因为资源分配的问题,有别的优先级更高的线程要运行,还没运行完就回到就绪状态。
线程运行过程中可能因为遇到某种阻塞事件进入阻塞状态
等到阻塞事件解除之后又回到就绪状态等待调用。
线程运行完之后才会终止
**
3.通过Callable接口实现线程
**
Callable接口实现线程是可以有返回值,通过实现Callable接口实现call方法即可。
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
但是线程执行最终是通过Thread类的start的方法,而Thread类不能通过Callable对象来构造。
但是Callable继承了FutureTask类,而FutureTask类实现了Runnable接口,即可以通过new Thread(FutureTask)来创建Thread
FutureTask里面有一个get方法可以获得call方法的返回值。
class Person<String> implements Callable<String>{
private int number =10;
public String call() throws Exception {
for(int i =0;i<10;i++) {
if(number>0) {
System.out.println(Thread.currentThread()+"-----"+number--);
}
}
return (String) ((String) Thread.currentThread()+"线程执行完毕");
}
}
public class Hello{
public static void main(String []args) throws InterruptedException, ExecutionException{
Person p = new Person();
//如果想获得返回值,那么这里可以
//FutureTask t = new FutureTask(p);
//t.get();
new Thread(new FutureTask(p)).start();
new Thread(new FutureTask(p)).start();
}
}
输出:
Thread[Thread-0,5,main]-----10
Thread[Thread-0,5,main]-----8
Thread[Thread-0,5,main]-----7
Thread[Thread-1,5,main]-----9
Thread[Thread-0,5,main]-----6
Thread[Thread-1,5,main]-----5
Thread[Thread-0,5,main]-----4
Thread[Thread-0,5,main]-----2
Thread[Thread-0,5,main]-----1
Thread[Thread-1,5,main]-----3