1、继承Thread类接口的实现方式
优点:代码简单
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"打印了第"+i+"次");
}
}
}
public class Thread接口 {
public static void main(String[] args) {
/*
多线程的第一种启动方式:
1、自己定一个Thread类
2、重写run方法
3、创建子类对象,并启动线程
*/
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.setName("线程一");
t2.setName("线程二");
t1.start();
t2.start();
}
}
2、实现Runnable接口的实现方式
优点:可以继承其他类,拓展性强
public class MyRUn implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Thread t=Thread.currentThread();//获取当前执行线程的对象
String name = t.getName();
System.out.println(name+"hello world!");
}
}
}
public class Run方法 {
public static void main(String[] args) {
/*
多线程的第二种启动方式
1、自己定义一个Runnable接口
2、重写里面的run方法
3、创建自己类的对象
4、创建一个Thread线程对象,并且开启线程
*/
MyRUn mr=new MyRUn();//如果在类中不写空参构造,系统会自动的补上一个空参构造。但是如果你写了有惨构造,你也必须写一个空参构造
Thread t1=new Thread(mr);
Thread t2=new Thread(mr);
//设置名字
t1.setName("线程1");
t2.setName("线程2");
t1.start();
t2.start();
}
}
3、实现Callable接口和Future接口的实现方式
优点:1、可以获取到线程运行后的结果 2、可以继承其他类,拓展性强
//第三种多线程实现的方式可以获取结果,所以你需要定义结果的类型
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
//求1-100的和
int sum=0;
for (int i = 0; i <=100; i++) {
sum+=i;
}
return sum;
}
}
public class 接口 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
/*
多线程的第三种实现方式:
特点:可以获取到多线程的运行结果
1、重写一个类MyCallable实现Callable接口
2、重写call(是有返回值的,表示实际多线程的运行结果)
3、创建MyCallable对象(表示多线程要执行的任务)
4、创建FutureTask对象(表示管理多线程运行的结果)
5、创建Thread类的对象,并启动(表示线程)
*/
//创建MyCallable对象(表示多线程要执行的任务)
MyCallable mc=new MyCallable();
//创建FutureTask对象,用这个对象去管理任务,并且放到线程里
FutureTask<Integer> ft=new FutureTask<>(mc);
//创建Thread类的对象,并启动(表示线程)
Thread t=new Thread(ft);//注意这里是调用ft
t.start();
//获取多线程运行的结果
Integer result = ft.get();
System.out.println(result);
}
}