200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > java线程三种创建方式与线程池的应用

java线程三种创建方式与线程池的应用

时间:2021-08-14 06:24:28

相关推荐

java线程三种创建方式与线程池的应用

前言:多线程下程序运行的结果是随机的,以下案例代码的运行结果仅供参考

一 通过继承Thread线程创建的方法与执行的步骤

/*1 继承Thread 2重写run方法 3创建线程继承类的子类4 调用start(一个线程只能通过调用一次start来进行启动)*/class MyThread extends Thread{public MyThread(String name){//调用Thread类中的构造方法才能顺序初始化成功线程名super(name);}@Overridepublic void run() {for (int i = 0; i < 3; i++) {//线程名(默认):Thread-0,currentThread是获取当前的线程System.out.println(Thread.currentThread().getName() + i);}}}public class ThreadTest {/*当前主线程是main线程,我们在此又开了个名为myThread的线程,main线程与thread线程的执行时顺序是随机的由于myThread的启动和被分配cpu时间片都需要时间,所以通常是main线程先执行只有start才能启动一个线程,启动后需要抢占cpu资源,抢占成功才能执行线程中的run方法,如果直接调用线程的run方法相当于在主线程main中正常的调用一个对象myThread的run方法若没有手动设置线程名称时,会自动分配一个线程的名称,如线程对象myThread会被自动分配线程名称Thread-0设置线程名称是为了区分当前正在执行的线程是哪一个线程,所以在设置线程名称时应避免重复!*/public static void main(String[] args) throws InterruptedException {MyThread myThread = new MyThread("myThread");//start方法是由新建态=> 就绪态。有两步①启动线程②调用线程的run方法myThread.start();System.out.println("========以下是main线程的执行步骤========");for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}}

二 通过实现Runnble的方法

/*①创建一个Runnable的实现类②实现类去重写接口的run方法③创建实现类的对象④将该对象作为参数传入到Thread构造器来构造一个Thread类型的对象⑤通过该thread对象调用时start*/class MyRun implements Runnable{@Overridepublic void run() {for (int i = 0; i < 3; i++) {//线程名(默认):Thread-0,currentThread是获取当前的线程System.out.println(Thread.currentThread().getName() + i);}}}public class ThreadTest {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new MyRun());thread.setName("mythread");thread.start();System.out.println("========以下是main线程的执行步骤========");for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}}

三、实现Callable的方式

方法三比方法二好,原因①call方法可以有返回值 ②Callable支持泛型③call可以声明抛出异常信息而run中不能

/*相比较Runable接口,call()方法新增捕获和抛出异常和返回值的功能,实现步骤如下:①创建一个Callable的实现类并重写call方法,将线程需要执行的任务写到call方法中②实例化一个该实现类的对象callable③将callable作为参数构造一个FutureTask的对象ftt④将ftt作为参数(Runnable接口类型的引用target)构造Thread对象thread⑤thread.start()启动线程补充:call的返回值类型即为Callable的泛型类型,通过ftt.get()可以返回call方法的返回值*/class MyCall implements Callable<Integer>{@Overridepublic Integer call() throws Exception {for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName() + ":" +i);}return 1;}}public class ThreadTest {public static void main(String[] args) throws InterruptedException, ExecutionException {Callable<Integer> callable = new MyCall();FutureTask<Integer> ftt = new FutureTask<Integer>(callable);Thread thread = new Thread(ftt);thread.start();System.out.println(ftt.get());}}

四、通过线程池的方式

由于线程的创建与销毁都是很耗费资源的工作,在高并发的情况下对性能影响非常大,解决:可以提前创建多个线程放入线程池,使用的时不是现造而是去线程池中取,使用完不是销毁而是重新放回线程池,避免频繁的创建于销毁,实现重复利用,类似于公交车,优势非常明显,降低响应时间(节约了创建线程的时间)节约系统资源(重复利用线程池的线程减少了创建和销毁线程的频率)提高系统系统,利于管理(例如可以通过参数指定线程池大小,池内最大线程数,线程保持时间)

class MyRun implements Runnable{@Overridepublic void run() {System.out.println("这是MyRun");}}class MyCall implements Callable{@Overridepublic Object call() throws Exception {return 1;}}/*1 创建一个指定线程数量的线程池对象service 2 将service强转为ThreadPoolExecutor以便设置线程池的属性3 需要传入Runnable或Callable接口实现类的对象(匿名对象)作为参数执行指定的线程的操作4 关闭连接池*/public class ThreadTest {public static void main(String[] args) throws InterruptedException, ExecutionException {//1 创建一个指定线程数量的线程池对象serviceExecutorService service = Executors.newFixedThreadPool(10);//2 将service强转为ThreadPoolExecutor以便设置线程池的属性ThreadPoolExecutor executor = (ThreadPoolExecutor)service;//3 需要传入Runnable或Callable接口实现类的对象(匿名对象)作为参数执行指定的线程的操作service.execute(new MyRun());service.submit(new MyCall());//4 关闭连接池service.shutdown();}}

推荐学习:线程的安全问题与三种解决方法

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。