线程的实现方式

        我们在创建一个线程时,是通过创建Thread实例完成线程的创建,但在具体的实现方式上可以有4种方式。

线程创建方式1:继承Thread

我们可以通过继承Thread类去重写run()方法来创建一个线程。代码参考实现如下:

//继承Thread,重写run()方法
class myThread extends Thread{
	public myThread(String name) {
		super(name);
	}
	@Override
	public void run() {
		for(int i=0;i<100;i++) {
			System.out.printf("[%s]=%d\n",this.getName(),i);
		}
	}
}

public static void main(String[] args) {
		myThread t1=new myThread("线程A");//创建线程
		
		t1.start();//启动线程
	}

线程创建方式2:实现Runnable接口

我们可以通过实现Runnable接口来重写run()方法,创建一个线程。代码参考如下:

class MailTask extends Task implements Runnable{

	@Override
	public void excute() {
		//获得当前线程对象
		Thread t=Thread.currentThread();
		System.out.println(t.getName()+"使用JavaMail技术发送邮件");
	}

	@Override
	public void run() {
		excute();
	}
	
}

abstract class Task{
	public abstract void excute();
}

public static void main(String[] args) {
		//每个Runnable接口的实现类,封装了线程执行逻辑
		MailTask mailTask=new MailTask();
		
		//创建3个线程
		Thread t1=new Thread(mailTask,"线程T1");
		Thread t2=new Thread(mailTask,"线程T2");
		Thread t3=new Thread(mailTask,"线程T3");
		
		//启动线程
		t1.start();
		t2.start();
		t3.start();
	}

线程创建方式3:实现Callable接口 

通过实现Callable接口重写它的call()方法也可以实现接口的创建,Callable和Runnable接口的区别在于Runnable的run()方法没有返回值,而Callable的call()方法有返回值,并且Callable的实现类需要通过FutureTask来包装后使用Thread(Future)来创建线程。代码参考实现如下:

//线程创建方式3:实现Callable接口
class SumCalcTask implements Callable{
	private int begin,end;
	public SumCalcTask(int begin,int end) {
		this.begin=begin;
		this.end=end;
	}
	
	@Override
	public Integer call() throws Exception {
		int sum=0;
		for(int i=begin;i<=end;i++) {
			sum+=i;
		}
		System.out.println(Thread.currentThread().getName());
		return sum;
	}
	
}

public static void main(String[] args) throws InterruptedException, ExecutionException {
		//Callable接口实现类:不同数据范围的计算任务
		SumCalcTask task1=new SumCalcTask(1, 300);
		SumCalcTask task2=new SumCalcTask(301, 500);
		SumCalcTask task3=new SumCalcTask(501, 1000);
		
		//Callable-->FutureTask(Runnable接口实现类)
		FutureTask futureTask1=new FutureTask(task1);
		FutureTask futureTask2=new FutureTask(task2);
		FutureTask futureTask3=new FutureTask(task3);
		
		//创建并开启线程
		Thread t1=new Thread(futureTask1);
		Thread t2=new Thread(futureTask2);
		Thread t3=new Thread(futureTask3);

		t1.start();
		t2.start();
		t3.start();
		
		System.out.println("开始分别获取。。。");
		Integer sum1=futureTask1.get();
		Integer sum2=futureTask2.get();
		Integer sum3=futureTask3.get();

		System.out.println("汇总各自计算结果:");
		Integer total=sum1+sum2+sum3;
		System.out.println("总和:"+total);
	}

线程创建方式4:通过线程池创建

通过线程池,我们也可以创建出一个线程,线程池中的线程不需要我们自己启动,他会自己启动线程,但使用完后我们需要使用shutdown()方法关闭线程池。代码实现参考如下:

public static void main(String[] args) {
		//固定数量(10)的线程池
		ExecutorService executorService=Executors.newFixedThreadPool(10);
		
		//不确定数量的线程请求
		while(true) {
			//向线程池提交一个执行任务(Runnable接口实现类对象)
			//线程池分配一个“空闲线程”执行该任务
			//如果没有空闲线程,则该任务进入“等待队列”(工作队列)
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					System.out.println(Thread.currentThread().getName()+"进行了一次投票!");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}

你可能感兴趣的:(jvm,java)