多线程的几种实现方式
常用方法:
方法一:继承Thread类
- 创建一个继承于Thread类的子类;
- 重写Thread类的run()方法;
- 创建Thread子类的对象;
- 通过对象调用start()方法;
案例一
package ThreadDemo;
public class MainThread {
public static void main(String[] args) {
DemoThread mt = new DemoThread();
mt.start();
new DemoSleep().start();
System.out.println(Thread.currentThread().getName());
}
}
package ThreadDemo;
public class DemoThread extends Thread{
@Override
public void run() {
String name = getName();
System.out.println(name);
}
}
方法二:
(1)
- 实现Runable接口方式
- 创建一个实现Runable接口的类
- 实现类区实现Runable中的抽象方法:run();
- 创建实现类的对象;
- 创建Thread类,将实现类对象作为参数传递到Thread类中;
- 通过Thread类对象调用start();
package RunnableImp;
public abstract class Runnable {
public static void main(String[] args) {
//创建Runnable的实现类对象
Demo01Runnable mt= new Demo01Runnable();
//创建Thread对象,构造方法传递Runnable接口的实现类对象
Thread t =new Thread(mt);
//传递不同的Runnable实现类对象,开启不同的线程
Thread t =new Thread(new Demo02Runnable());
//开启线程
t.start();
}
}
package RunnableImp;
public class Demo01Runnable implements java.lang.Runnable {
@Override
public void run() {
for ( int i = 0 ; i <20 ; i++ ) {
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
package RunnableImp;
public class Demo02Runnable implements java.lang.Runnable {
@Override
public void run() {
for ( int i = 0 ; i <20 ; i++ ) {
System.out.println("Hello World"+i);
}
}
}
(2)
- 实现callable接口方式,与run相比,call方法可以有返回值,可以通过FetureTask类接受返回值;
package RunnableImp;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Callable {
public static void main(String[] args){
//new一个实现callable接口的对象
NumThread numThread = new NumThread();
//通过futureTask对象的get方法来接收futureTask的值
FutureTask futureTask = new FutureTask(numThread);
FutureTask futureTask2 = new FutureTask(numThread);
Thread t1 = new Thread(futureTask);
Thread t2 = new Thread(futureTask2);
t1.setName("线程1");
t1.start();
t2.setName("线程2");
t2.start();
try {
//get返回值即为FutureTask构造器参数callable实现类重写的call的返回值
Object sum = futureTask.get();
Object sum2 = futureTask2.get();
System.out.println(Thread.currentThread().getName()+":"+sum);
System.out.println(Thread.currentThread().getName()+":"+sum2);
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package RunnableImp;
import java.util.concurrent.Callable;
public class NumThread implements Callable {
private int sum=0;//
@Override
public Object call() throws Exception {
for(int i = 0;i<=100;i++){
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName()+":"+i);
sum += i;
}
}
return sum;
}
}
方法三:创建线程池
- 相关API:ExcutorService和Excutors;
- Future.submit(Callable task):执行任务,有返回值;
- void shutdown():关闭线程池;
package ThreadPool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
* Executors类中的静态方法: Static ExecutorService newFixedThreadPool(int nThreads)
* 返回值:ExecutorService接口,返回的是ExecutorService接口的实现类对象
* */
public class Demo01ThreadPool {
public static void main(String[] args) {
//创建线程池
ExecutorService ex = Executors.newFixedThreadPool(2);
//启动线程
ex.submit(new RunnablImp());
ex.submit(new RunnablImp());
ex.submit(new RunnablImp());
//销毁线程
ex.shutdown();
}
}
package ThreadPool;
public class RunnablImp implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}