java线程池创建的三种方式(java 线程池创建)
JAVA线程能创建线程吗
Java有三种创建线程的方式,分别是继承Thread类、实现Runable接口和使用线程池
1、继承Thread类
使用该方式创建及使用线程需按以下三个步骤:
(1)定义Thread类的子类,并重写父类的run()方法,方法里的内容就是线程所要执行的任务;
(2)创建子类的实例,即生成线程的实例对象;
(3)调用现成的start()方法来启动线程。
public class SubThread extends Thread {
private int ticket = 100; private String name; public ImplThread(String name) { this.name = name;
} public void run() { while (k 0){
System.out.println(ticket-- + "is saled by" + name);
} try{
sleep((int)Math.random() * 10);
}catch (InterruptedException e){
e.printStackTrace();
}
} public static void main (String []args){
SubThread t1 = new SubThread("A");
SubThread t2 = new SubThread("B");
t1.start();
t2.start();
}
}1234567891011121314151617181920212223
2、实现Runnable接口
(1)定义实现Runnable接口的实现类,并重写run()方法;
(2)创建Runnable接口实现类的实例,并将该实例作为参数传到Thread类的构造方法中来创建Thread对象,该Thread对象才是真正的线程对象;
(3)调用现成的start()方法来启动线程。
public class ImplThread implements Runnable {
private int ticket = 100; private String name; public ImplThread(String name) { this.name = name;
} public void run() { while (k 0){
System.out.println(ticket-- + "is saled by" + name);
} try{
sleep((int)Math.random() * 10);
}catch (InterruptedException e){
e.printStackTrace();
}
} public static void main (String []args){
ImplThread i1 = new ImplThread("A");
ImplThread i2 = new ImplThread("B");
Thread t1 = new Thread(i1);
Thread t2 = new Thread(i2);
t1.start();
t2.start();
}
}12345678910111213141516171819202122232425
上面这段代码跟继承Thread类的线程代码呈现的效果是一样的,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。
但是,在某些场景,我们希望各线程能共享资源,这时候就只能扩展Runnable接口了。
public class ImplThread implements Runnable {
private int ticket = 100; public void run() { while (k 0){
System.out.println(ticket-- + "is saled by" + Thread.currentThread());
} try{
sleep((int)Math.random() * 10);
}catch (InterruptedException e){
e.printStackTrace();
}
} public static void main (String []args){
ImplThread i = new ImplThread();
Thread t1 = new Thread(i);
Thread t2 = new Thread(i);
t1.start();
t2.start();
}
}1234567891011121314151617181920
这时候,线程t1和t2共享这100张票。
3、使用线程池
使用线程池并不是创建线程,而是对线程进行管理。Excetor为线程池超级接口,该接口中定义了一个execute(Runnable command)方法,用来执行传递过来的线程,ExecutorService就是我们所说的线程池,它继承了Excetor接口。如何创建线程池呢?Java提供了Executors类,该类有四个静态方法分别可以创建不同类型的线程池(ExecutorService)。
Executors.newCachedThreadPool() 创建可变大小的线程池
Executors.newFixedThreadPool(int number) 创建固定大小的线程池
Executors.newSingleThreadPool() 创建单任务线程池
Executors.newScheduledThreadPool(int number) 创建延迟线程池
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class Test { public static void main(String[] args) {
//创建一个可重用固定线程数的线程池 ExecutorService pool = Executors.newFixedThreadPool(2);
//创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread t1 = new MyThread();
Thread t2 = new MyThread();
Thread t3 = new MyThread();
Thread t4 = new MyThread();
Thread t5 = new MyThread();
//将线程放入池中进行执行 pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
//关闭线程池 pool.shutdown();
}
}
class MyThread extends Thread{ @Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在执行。。。");
}
} 12345678910111213141516171819202122232425262728
输出:
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
Process finished with exit code 0
可见,线程得到了重用,线程池里只有两个线程在执行。

创建线程有几种方式和Java中常用的线程池
java创建线程的方式有三种
第一种是继承Thread类 实现方法run() 不可以抛异常 无返回值
第二种是实现Runnable接口 实现方法run() 不可以抛异常 无返回值
第三种是实现CallableT接口,接口中要覆盖的方法是 public T call() 注意:此方法可以抛异常,而前两种不能 而且此方法可以有返回值
第三种如何运行呢 Callable接口在util.concurrent包中,由线程池提交
import java.util.concurrent.*;
ExecutorService e = Executors.newFixedThreadPool(10); 参数表示最多可以运行几个线程
e.submit(); 这个里面参数传 实现Callable接口那个类的对象
线程池的创建
new ThreadPoolExecutor(corePoolSize, maxinumPoolSize, keepAliveTime, milliseconds, runnableTaskQueue, handler);
参数简介:
当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其它空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不会再创建。如果调用了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有基本线程。
用于保存等待执行的任务的阻塞队列,可以有以下选择:
ArrayBlockingQueue :是一个基于数组结构的有界阻塞队列,此队列按FIFO(先进先出)原则对元素进行排序
LinkedBlockingQueue :一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量通常高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
SynchronousQueue :一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool()使用了这个队列。
PriorityBlockingQueue :一个具有优先级的无限阻塞队列
线程池被允许创建的最大线程数,如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。需要注意的是,如果使用了无界的阻塞队列,那么这个参数也就没什么效果。
当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。在JDK1.5中Java线程池框架提供了以下4中策略。
AbortPolicy :直接抛出异常
CallerRunsPolicy :只用调用者所在线程来运行任务
DiscardOldestPolicy :丢弃队列里最近的一个任务,并执行当前任务
DiscardPolicy :不处理,丢弃掉
线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,每个任务执行的时间比较短,可以调大时间,提高线程的利用率
可选单位有天(DAYS)、小时(HOURS)、分钟(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)、纳秒(NANOSECONDS,千分之一微秒)
线程池的几种常见的创建的方式
一:创建大小不固定的线程池
二:创建固定数量线程的线程池
三:创建单线程的线程池
四:创建定时线程
1.创建大小不固定的线程池
[java]?view plain?copy
package?com.peace.pms.Test;
import?java.util.concurrent.ExecutorService;
import?java.util.concurrent.Executors;
/**
*?@Author:?cxx
*?@Date:?2018/3/3?17:16
*/
public?class?ThreadPoolDemo?{
public?static?class?Taskdemo?implements?Runnable{
@Override
public?void?run()?{
for(int?i=0;i10;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public?static?void?main(String[]?args)?{
ExecutorService?es=Executors.newFixedThreadPool(2);
for(int?i=0;i10;i++){
Taskdemo?tc=new?Taskdemo();
es.execute(tc);
}
es.shutdown();
}
}
2.创建固定数量线程的线程池
[java]?view plain?copy
public?static?void?main(String[]?args)?{
ExecutorService?es=Executors.newFixedThreadPool(2);
for(int?i=0;i10;i++){
Taskdemo?tc=new?Taskdemo();
es.execute(tc);
}
es.shutdown();
}
3.创建单线程的线程池
[java]?view plain?copy
public?static?void?main(String[]?args)?{
ExecutorService?es=Executors.newSingleThreadExecutor();
for(int?i=0;i10;i++){
Taskdemo?tc=new?Taskdemo();
es.execute(tc);
}
es.shutdown();
}
4.创建定时线程
[java]?view plain?copy
public?static?void?main(String[]?args)?{
ScheduledExecutorService?es=Executors.newScheduledThreadPool(2);
for(int?i=0;i10;i++){
Taskdemo?tc=new?Taskdemo();
//参数1:目标对象
//参数2:隔多长时间开始执行线程,
//参数3:执行周期
//参数4:时间单位
es.scheduleAtFixedRate(tc,?30,?10,?TimeUnit.MILLISECONDS);
}
es.shutdown();
}
java创建线程的方式有几种?
java创建线程的方式有三种
第一种是继承Thread类 实现方法run() 不可以抛异常 无返回值
第二种是实现Runnable接口 实现方法run() 不可以抛异常 无返回值
第三种是实现CallableT接口,接口中要覆盖的方法是 public T call() 注意:此方法可以抛异常,而前两种不能 而且此方法可以有返回值
第三种如何运行呢 Callable接口在util.concurrent包中,由线程池提交
import java.util.concurrent.*;
ExecutorService e = Executors.newFixedThreadPool(10); 参数表示最多可以运行几个线程
e.submit(); 这个里面参数传 实现Callable接口那个类的对象