第一种,实现Runnable接口
publicclassMyThreadimplementsRunnable { publicvoidrun() { System.out.println("hello world"); } publicstaticvoidmain(String[] args) { MyThreadmyThread=newMyThread(); Threadthread=newThread(myThread); thread.start(); } }
第二种,继承Thread类
publicclassMyThread1extendsThread { publicvoidrun() { System.out.println("hello"); } publicstaticvoidmain(String[] args) { newMyThread1().start(); } }
第三种,实现Callable接口
publicclassMyThread2implementsCallable<String> { publicStringcall() throwsException { System.out.println("call----"); return"call"; } publicstaticvoidmain(String[] args) throwsExecutionException, InterruptedException { FutureTask<String>futureTask=newFutureTask<>(newMyThread2()); newThread(futureTask, "A").start(); System.out.println(futureTask.get()); } }
第四种,通过线程池获取线程
开发规范手册中推荐使用的
不要显式创建线程,请使用线程池。
当然
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
Executors返回的线程池对象的弊端如下:
1)FixedThreadPool和SingleThreadPool
允许的请求队列长度为Integer.MAX_VALUE(约为21亿),可能对堆积大量的请求,从而导致OOM
2)CacheThreadPool和ScheduledThreadPool
允许创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM
/*** 7个参数* 核心线程池大小* 最大核心线程池大小* 超时了没有人调用就会释放* 超时单位* 阻塞队列* 线程工厂:创建线程的,一般不用动Executors.defaultThreadFactory()* 拒绝策略*/publicThreadPoolExecutor(intcorePoolSize, intmaximumPoolSize, longkeepAliveTime, TimeUnitunit, BlockingQueue<Runnable>workQueue, ThreadFactorythreadFactory, RejectedExecutionHandlerhandle) { }
四种拒绝策略:
- new ThreadPoolExecutor.AbortPolicy() // 池满了,还有进来的,不处理,抛出异常
- new ThreadPoolExecutor.CallerRunsPolicy() // 哪来的去哪里!
- new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常!
- new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和最早的竞争,也不会抛出异常!
线程池的最大的大小如何设置?
- CPU 密集型,几核,就是几,可以保持CPU的效率最高!
- IO 密集型,判断程序中十分耗IO的线程
获取CPU的核数
System.out.println(Runtime.getRuntime().availableProcessors());