java线程创建的方法

3 篇文章 0 订阅

 

 第一种方法:继承Thread

public class MyThread extends Thread{
	public static void main(String[] args) {
		/**
		 * 1 继承Thread类 重写run(),Thread.start()
		 */
		MyThread t = new MyThread();
		t.start();
	}

	@Override
	public void run() {
		System.out.println("启动线程");
	}
	
	
}

第二种方法:实现Runnable

public class MyThread{
	public static void main(String[] args) {
		
		showTimeTask task = new showTimeTask();
		Thread t = new Thread(task);
		t.start();
		
	}

}

//实现Runnable接口
	class showTimeTask implements Runnable{
		boolean flag = true;
		@Override
		public void run() {
			while(flag){
				Date d = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				System.out.println("线程2:  showTimeTask当前时间:"+sdf.format(d));
				
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		
	}

匿名类(也算是第二种方法实现Runnable)

public class MyThread{
	public static void main(String[] args) {
		Runnable r = new Runnable() {
			//Runnable 是接口
			boolean flag = true;
			@Override
			public void run() {
				while(flag){
					Date d = new Date();
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					System.out.println("线程当前时间:"+sdf.format(d));
					
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
	 	Thread t2 = new Thread(r);
		t2.start();
	}

}

---------------------------------使用Callable和Future创建线程------------------------------

 

第三种方法:实现Callable接口

实现Callable与Runnable不同,Callable接口提供的是一个call()方法作为线程执行体,call()比run()更强大:

1)call()有返回值

2)call()可以声明抛出异常

public class MyThread{
	public static void main(String[] args) {
		try {
			Test t = new MyThread().new Test();
			t.call();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	class Test implements Callable{
		@Override
		public Object call() throws Exception {
			System.out.println("开启线程");
			return null;
		}
		
	}

}

 

第四种方法:实现Futrue接口

Java5提供了Future接口来代表Callable接口里call()方法的返回值,并且为Future接口提供了一个实现类FutureTask,这个实现类既实现了Future接口,还实现了Runnable接口,因此可以作为Thread类的target。在Future接口里定义了几个公共方法来控制它关联的Callable任务。

>boolean cancel(boolean mayInterruptIfRunning):视图取消该Future里面关联的Callable任务

>V get():返回Callable里call()方法的返回值,调用这个方法会导致程序阻塞必须等到子线程结束后才会得到返回值

>V get(long timeout,TimeUnit unit):返回Callable里call()方法的返回值,最多阻塞timeout时间,经过指定时间没有返回抛出TimeoutException

>boolean isDone():若Callable任务完成,返回True

>boolean isCancelled():如果在Callable任务正常完成前被取消,返回True

介绍了相关的概念之后,创建并启动有返回值的线程的步骤如下:

public class MyThread{
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		 FutureTask<Double> task = new FutureTask(new MyCallable());
		    //创建一个线程,异步计算结果
		    Thread thread = new Thread(task);
		    thread.start();
		    //主线程继续工作
		    Thread.sleep(1000);
		    System.out.println("主线程等待计算结果...");
		    //当需要用到异步计算的结果时,阻塞获取这个结果
		    Double d = task.get();
		    System.out.println("计算结果是:"+d);

		    //用同一个 FutureTask 再起一个线程
		    Thread thread2 = new Thread(task);
		    thread2.start();
	}
}
	class MyCallable implements Callable<Double>{

	    @Override
	    public Double call() {
	         double d = 0;
	         try {
	             System.out.println("异步计算开始.......");
	              d = Math.random()*10;
	             d += 1000;
	            Thread.sleep(2000);
	             System.out.println("异步计算结束.......");
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
	        return d;
	    }
	}

第五种方法:使用线程池ExecutorSerice、Executors

 

  前面三种方法,都是显式地创建一个线程,可以直接控制线程,如线程的优先级、线程是否是守护线程,线程何时启动等等。而第四种方法,则是创建一个线程池,池中可以有1个或多个线程,这些线程都是线程池去维护,控制程序员不需要关心这些细节,只需要将任务提交给线程池去处理便可,非常方便。
  创建线程池的前提最好是你的任务量大,因为创建线程池的开销比创建一个线程大得多

创建线程池的方式

  ExecutorService 是一个比较重要的接口,实现这个接口的子类有两个 ThreadPoolExecutor (普通线程池)、ScheduleThreadPoolExecutor (定时任务的线程池)。你可以通过这两个类来创建一个线程池,但要传入各种参数,不太方便。
  为了方便用户,JDK中提供了工具类Executors,提供了几个创建常用的线程池的工厂方法。

public class MyThread{
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		//创建一个只有一个线程的线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        //创建任务,并提交任务到线程池中
        executorService.execute(new MyRunable("任务1"));
        executorService.execute(new MyRunable("任务2"));
        executorService.execute(new MyRunable("任务3"));
	}
}
class MyRunable implements Runnable{

    private String taskName;

    public MyRunable(String taskName) {
        this.taskName = taskName;
    }

    @Override
    public void run() {
        System.out.println("线程池完成任务:"+taskName);
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值