java线程池创建的三种方式(java 线程池创建)

http://www.itjxue.com  2023-01-29 17:23  来源:未知  点击次数: 

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接口那个类的对象

(责任编辑:IT教学网)

更多

推荐网络媒体文章