一.继承Thread类和重写run()方法导读
闲暇周末,怎能懒惰?乘此风和日丽之日,来死磕一下java多线程的创建和启动
public class MyThread extends Thread { private String name; public MyThread(String name) { this.name = name; } @Override public void run() { System.out.println(name+"执行了"); } public static void main(String[] args) { MyThread mt1 = new MyThread("线程1"); mt1.start(); } }
执行结果:
public class MyRunnable implements Runnable{ private String name; public MyRunnable(String name) { this.name = name; } @Override public void run() { System.out.println(name+"执行了"); } public static void main(String[] args) { MyRunnable runnable = new MyRunnable("线程2"); Thread thread = new Thread(runnable); thread.start(); } }
执行结果:
public class InnerClass { public static void main(String[] args) { //方式1:相当于继承了Thread类,作为子类重写run()实现 new Thread() { public void run() { System.out.println("匿名内部类创建线程方式1..." + Thread.currentThread().getName()); } }.start(); //方式2:实现Runnable,Runnable作为匿名内部类 new Thread(new Runnable() { public void run() { System.out.println("匿名内部类创建线程方式2..." + Thread.currentThread().getName()); } }).start(); //方式3:Lambda表达式创建线程 new Thread(() -> { System.out.println("Lambda表达式创建线程方式..." + Thread.currentThread().getName()); }).start(); } }
执行结果:
public class ThreadPool { public static void main(String[] args) { //创建一个可缓存的线程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); for (int i = 0; i < 10; i++) { final int index = i; fixedThreadPool.execute(new Runnable() { public void run() { try { System.out.println(index+ " "+Thread.currentThread().getName()+" "+ DateUtils.getNowDate()); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } fixedThreadPool.shutdown(); } }
执行结果:
newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool
创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。FixedThreadPool是一个典型且优秀的线程池,它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是,在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源。
newSingleThreadExecutor
创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。
newScheduleThreadPool
建一个定长的线程池,而且支持定时的以及周期性的任务执行,支持定时及周期性任务执行。
继承Thread类和实现了Runnable接口这2种方式创建线程都有一个缺陷就是:在执行完任务之后无法获取执行结果。
自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。
更多内容请大家学习这篇博客,写的非常棒.Java并发编程:Callable、Future和FutureTask
public class CallableTest { public static void main(String[] args) { ExecutorService executor = Executors.newCachedThreadPool(); MyCallable task = new MyCallable(); Future<Integer> result = executor.submit(task); executor.shutdown(); try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("主线程在执行任务"); try { System.out.println("task运行结果"+result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("所有任务执行完毕"); } }
public class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println("子线程在进行计算"); Thread.sleep(3000); int sum = 0; for(int i=0;i<100;i++) sum += i; return sum; } }总结
综上所述,我们总结了Java日常开发中多线程创建的多种方式和启动方式.若大家有好的办法,请在评论里面留言.