1.继承Thread类,子类要重写run()方法,如:
public class MyThread extends Thread{
/**
* 线程执行的逻辑体
*/
@Override
public void run(){
for(int i=1;i<=100;i++) {
//this.getName:获取当前线程名称
System.out.println(this.getName()+"下载了" + i + "%");
}
}
public static void main(String args[]){
//创建一个线程对象
MyThread myThread = new MyThread();
//启动一个线程
myThread.start();
}
}
*注意:启动线程调用start方法为用异步方式启动线程,如果调用run方法则为同步方式启动线程(普通调用)
2.实现Runnable接口,实现run()方法,如:
public class MyRunnable implements Runnable{
private String name;
public MyRunnable (String name) {
this.name = name;
}
@Override
public void run(){
for(int i=1;i<=100;i++) {
//this.getName:获取当前线程名称
System.out.println(name+"下载了" + i + "%");
}
}
public static void main(String args[]){
//创建线程对象
Thread myThread1 = new Thread(new MyRunnable("爱的供养"));
Thread myThread2 = new Thread(new MyRunnable("告白气球"));
//启动线程
myThread1.start();
myThread2.start();
}
}
以上两种方法只是实现方式不用,核心不变,都是实现run方法
3.实现Callable接口,实现call()方法
public class MyCallable{
public static void main(String[] args) {
ThreadDemo td = new ThreadDemo();
// 1.执行Callable方式,需要FutureTask实现类的支持,用于接收运算结果
FutureTask<Integer> result = new FutureTask<>(td);
new Thread(result).start();
// 2.接收线程运算后的结果
Integer sum;
try {
//等所有线程执行完,获取值,因此FutureTask 可用于 闭锁
sum = result.get();
System.out.println("-----------------------------");
System.out.println(sum);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
class ThreadDemo implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100000; i++) {
System.out.println(i);
sum += i;
}
return sum;
}
}
*注意:get方法是阻塞的,即:线程无返回结果,get方法会一直等待
4.使用ExecutorService、Callable、Future实现有返回结果的线程
核心还是实现Callable接口,具体参考有返回值的线程池使用