创建线程的4种方式
方式一:继承Thread类
1>定义子类继承Thread类;
2>子类中重写Thread类中的run方法;
3>创建Thread子类对象,创建了线程对象;
4>调用线程的start方法:启动线程,调用run方法。
eg:
public class API01 {
public static void main(String[] args) {
//创建线程
MyThread mt = new MyThread();
//启动线程,并调用当前线程的run方法
mt.start(); //启动多线程必须要调用start方法,一个线程对象只能调用一次start()方法启动;
}
}
//定义子类继承Thread类
class MyThread extends Thread{
public MyThread(){}
//重写run方法
public void run(){
for(int i = 0;i<100;i++){
System.out.println("子线程:"+i);
}
}
}
方式二:实现Runnable接口
1>定义子类,实现Runnable接口;
2>子类中重写Runnable接口中的run方法;
3>通过Thread类含参构造器创建线程对象;
4>将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中;
5>调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法;
public class API02 {
public static void main(String[] args) {
//通过Thread类含参构造器创建线程对象;接口的子类对象作为参数传递给Thread类的构造器中;
Thread t =new Thread(new RightRunnable());
//调用Thread类中的start方法,开启线程,调用Runnable子类接口的run方法;
t.start();
}
}
//定义子类,实现Runnable接口;
class RightRunnable implements Runnable{
//子类中重写Runnable接口中的run方法;
public void run(){
for(int i =0;i<50;i++){
System.out.println(Thread.currentThread().getName()+"说:右手慢动作重播");
}
}
}
方式三:使用Callable和Future接口创建线程
具体是创建Callable接口的实现类,并实现call()方法。并使用FutureTask类来包装Callable实现类的对象,且以此 FutureTask对象作为Thread对象的target来创建线程;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CRable2 {
public static void main(String[] args)throws IOException, InterruptedException, ExecutionException {
FutureTask[] fs = new FutureTask[10];
for(int i = 1;i<=10;i++){
//创建MyCallable对象
Callable<Integer> c = new MyCallable(100*(i-1)+1,i*100);
//使用futureTask来包装MyCallable对象;
FutureTask<Integer> f = new FutureTask<Integer>(c);
//FutureTask对象作为Thread对象的target创建新的线程
Thread t1 = new Thread(f);
fs[i-1] = f;
//线程进入就绪状态;
t1.start();
}
int res = 0;
for(FutureTask tmp:fs)
//取得新创建的线程中call()方法返回的结果;
res+=(Integer)tmp.get();
System.out.println("1+2+3+4..+1000="+res);
}
}
class MyCallable implements Callable<Integer>{
private int begin = 0;
private int end = 0;
public MyCallable(int begin,int end){
this.begin =begin;
this.end = end;
}
public Integer call() throws Exception{
int res = 0;
for(int i =begin;i<=end;i++){
res += i;
}
return res;
}
}
方法四:使用线程池创建线程
享元模式
享元模式Flyweight Pattern主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于 结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式
优点:大大减少对象的创建,降低系统内存的使用,以提高程序的执行效率。
缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部 状态的变化而变化,否则会造成系统的混乱。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class XianxingChi04 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建一个固定大小的连接池,经常实现使用少量线程以对应波峰请求;
ExecutorService es = Executors.newFixedThreadPool(3);
//为了使用返回结果所以使用Callable;
Future[] fs = new Future[10];
for(int i =0;i<10;i++){
Callable c = new MyCallable(i*100 +1,(i+1)*100);
//使用线程池执行任务并获取Future对象;
fs[i] = es.submit(c);
}
int res = 0;
for(Future tmp :fs){
Object obj = tmp.get();
if(obj != null&&obj instanceof Integer)
res +=(Integer)obj;
}
//关闭线程池;
es.shutdown();
System.out.println("Main:"+res);
}
static class MyCallable implements Callable<Integer>{
private int begin = 0;
private int end = 0;
public MyCallable(int begin,int end){
this.begin =begin;
this.end = end;
}
public Integer call() throws Exception{
int res = 0;
for(int i =begin;i<=end;i++){
res += i;
}
return res;
}
}
}
使用ExecutorService、Callable、Future实现有返回结果的线程 ,连接池的具体实现实际上是依赖于 ThreadPoolExecutor