使用多线程的几种方式以及对比
1.继承Thread类
实现方式很简单, 只需创建一个类去继承Thread类然后重写run方法,在main方法中调用改实例对对象即可实现多线程并发。
public static void main(String[] args) {
Thread t1 = new MyThread("线程1");
t1.start();
}
class MyThread extends Thread{
/*线程名称*/
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("名称" + name + "的线程ID是:" + Thread.currentThread().getId());
}
}
2.继承Runnable接口
实现方式也很简单,只需创建一个类去实现接口Runnable,在main方法中调用该实例对象即可实现多线程并发
public static void main(String[] args) {
MyRunnable r1 = new MyRunnable("线程1");
Thread t1 = new Thread(r1);
t1.start();
}
public class MyRunnable implements Runnable{
private String name;
public MyRunnable(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("名字" + name + "的线程ID是: " + Thread.currentThread().getId());
}
}
3.使用Callable和Future创建线程
3.1 调用FutureTask(Callable<V> callable)返回程序方法中的结果
public static void main(String[] args) {
Callable callable = new MyCallable();
FutureTask futureTask = new FutureTask(callable);
new Thread(futureTask,"子线程"+ i).start();
try {
//获取子线程的返回值
System.out.println("子线程返回值:"+futureTask.get() + "\n");
} catch (Exception e) {
e.printStackTrace();
}
}
public class MyCallable implements Callable {
int i = 0;
@Override
public Object call() throws Exception {
System.out.println(Thread.currentThread().getName() + " i的值:"+ i);
return i++;
}
}
3.2 调用FutureTask(Runnable runnable, V result)返回给定的返回值(result)
MyRunnable myRunnable = new MyRunnable("线程");
FutureTask futureTask = new FutureTask(myRunnable, "shdgf");
new Thread(futureTask,"子线程").start();
try {
//获取子线程的返回值
System.out.println("子线程返回值:"+futureTask.get() + "\n");
} catch (Exception e) {
e.printStackTrace();
}
public class MyRunnable implements Runnable{
private String name;
public MyRunnable(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("名字" + name + "的线程ID是: " + Thread.currentThread().getId());
}
}
以上的3种方式进行对比与总结
对比:第一种方式相对简单,直接start,不需要其它的转换;第二种方式实现其它的接口,使开发更加灵活;第三种方式可以有返回值,可以抛出异常。
总结:在实际的开发中,可能会有更加复杂的代码,需要继承其它的类,所以推荐Runnable的方式来实现,使得代码更加的简洁灵活。至于第二种方式和第三种方式的选择,就得根据业务需要,是否需要返回值和是否需要抛出异常。