Java中线程创建的方式
1 继承Thread
格式:
class 类名 extends Thread{
//重写run()方法
public void run(){
//这里的代码就是一条新的执行路径。
//这个执行路径的触发方式不是调用run方法,而是通过thread对象的start来启动任务
}
}
示例:
public class Demo {
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
for (int i = 0; i < 10; i++) {
System.out.println("汗滴禾下土" + i);
}
}
}
class MyThread extends Thread{
/**
* run方法就是线程要执行的任务方法
*/
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("锄禾日当午" + i);
}
}
}
运行结果:抢占式调度,运行结果不唯一。
锄禾日当午0
汗滴禾下土0
锄禾日当午1
锄禾日当午2
汗滴禾下土1
锄禾日当午3
汗滴禾下土2
锄禾日当午4
汗滴禾下土3
锄禾日当午5
汗滴禾下土4
锄禾日当午6
汗滴禾下土5
锄禾日当午7
汗滴禾下土6
锄禾日当午8
汗滴禾下土7
锄禾日当午9
汗滴禾下土8
汗滴禾下土9
2 实现Runnable
格式:
class 类名 implements Runnable{
public void run(){
//线程要执行的任务
}
}
示例:
public class Demo2 {
public static void main(String[] args) {
//实现Runnable
//1. 创建一个任务对象
MyRunnable m = new MyRunnable();
//2. 创建一个线程,并为其分配一个任务
Thread t = new Thread(m);
//3. 执行这个线程
t.start();
for (int i = 0; i < 10; i++) {
System.out.println("疑是地上霜" + i);
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
//线程的任务
for (int i = 0; i < 10; i++) {
System.out.println("床前明月光" + i);
}
}
}
运行结果:抢占式调度,运行结果不唯一。
疑是地上霜0
床前明月光0
疑是地上霜1
床前明月光1
疑是地上霜2
床前明月光2
床前明月光3
床前明月光4
床前明月光5
床前明月光6
床前明月光7
疑是地上霜3
床前明月光8
疑是地上霜4
床前明月光9
疑是地上霜5
疑是地上霜6
疑是地上霜7
疑是地上霜8
疑是地上霜9
实现Runnable 与 继承Thread相比有如下优势:
- 通过创建任务,然后给线程分配的方式来实现多线程,更适合多个线程同时执行相同任务的情况。
- 可以避免单继承带来的局限性。
- 任务与线程本身是分离的,提高了程序的健壮性。
- 线程池技术,接收Runnable类型的任务,不接收Thread类型的线程。
3 实现Callable
格式:
class 类名 implements Callable<T>{
T call() throws Exception{
//线程执行的任务
return T;
}
}
示例:
public class Demo11 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> c = new MyCallable();
FutureTask<Integer> task = new FutureTask<Integer>(c);
new Thread(task).start();
Integer j = task.get();
System.out.println("返回值:" + j);
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
}
static class MyCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(i);
}
return 100;
}
}
}
运行结果:
0
1
2
3
4
5
6
7
8
9
返回值:100
0
1
2
3
4
5
6
7
8
9
4 线程池
以定长线程池为例显示:
public class Demo{
public static void main(String[] args){
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "锄禾日当午");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "锄禾日当午");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "锄禾日当午");
}
});
}
}
运行结果:
pool-1-thread-1锄禾日当午
pool-1-thread-2锄禾日当午
pool-1-thread-1锄禾日当午