Java中开启多线程的三种方法

您所在的位置:网站首页 java多线程几种实现方式 Java中开启多线程的三种方法

Java中开启多线程的三种方法

2024-02-17 14:49| 来源: 网络整理| 查看: 265

Java开启多线程有三种方式: 继承Thread类,重写run方法实现Runnable接口,重写run方法实现Callable接口,重写call方法(juc并发包中,用的不多)

 

方式一:直接继承Thread类,重写run()方法

执行线程必须调用start()方法,从而加入到调度器中不一定立即执行,系统安排调度分配执行(等待分配时间片)直接调用run()方法不是开启线程,是普通方法调用使用继承Thread类的方法来创建线程类时,多个线程之间无法共享线程类的实例变量(成员变量) /** * 创建多线程方法一: * 1、创建:继承Thread + 重写run()方法 * 2、启动:创建子类对象 + start() */ public class StartThread extends Thread{ //多线程入口 @Override public void run() { for(int i = 0; i < 50; i++){ System.out.println("一边听音乐"); } } public static void main(String[] args) { //创建子对象 StartThread st = new StartThread(); //启动 st.start(); //开启多线程,不保证立即调用,调度交由CPU //st.run(); //调用普通方法,正常的逻辑顺序流 for(int i = 0; i < 50; i++){ System.out.println("一边coding"); } } }

打开start()原码,会发现start()会调用本地方法start0(),再本地方法start0()中会调用run()方法。

 

方式二:实现Runnable接口,重写run()方法

java中存在单继承的局限性,因此建议多采用实现,少用继承,也就是多用Runable接口方便共享资源,一份资源多个代理Runnable对象仅仅作为Thread对象的target,Runnable实现类里包含的run()方法仅作为线程执行体。而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法。 /** * 创建多线程方法二: * 1、创建:实现Runnable中的run()方法 * 2、启动:创建实现类对象 + 代理类Thread对象 + start() */ public class StartRun implements Runnable{ //多线程入口 @Override public void run() { for(int i = 0; i < 50; i++){ System.out.println("一边听音乐"); } } public static void main(String[] args) { //创建实现类对象 StartRun sr = new StartRun(); //创建代理类对象 Thread t = new Thread(sr); //启动 t.start(); //开启多线程,不保证立即调用,调度交由CPU for(int i = 0; i < 50; i++){ System.out.println("一边coding"); } } }

 由于sr和t只用了一次,所以建议采用匿名类

public class StartRun implements Runnable{ //多线程入口 @Override public void run() { for(int i = 0; i < 50; i++){ System.out.println("一边听音乐"); } } public static void main(String[] args) { new Thread(new StartRun()).start(); for(int i = 0; i < 50; i++){ System.out.println("一边coding"); } } }

针对方法二中,一份资源,多份代理,实现资源共享,这里以一个简单地实例说明

ctrl + alt + t 快速加上try-catch代码 /** * 资源共享,并发编程(需要保证线程安全,后续讲解) * ctrl + alt + p 快速加上try-catch代码 */ public class Web12306 implements Runnable { private int ticketNumbs = 10; @Override public void run() { while(true) { if (ticketNumbs { int i = 0; for(; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "的循环变量i的值: " + i); } return i; //call()方法可以有返回值 }); for(int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "的循环变量i的值: " + i); if(i == 20) { //实例还是以Callable的封装对象来创建并启动线程的 new Thread(task, "有返回值的线程").start(); } } try { System.out.println("子线程的返回值:" + task.get()); //获取线程返回值 } catch (Exception e) { e.printStackTrace(); } } }

运行结果:交替执行主线程和子线程,以下结果仅仅作为显示,因为各打印100行,太占篇幅

main的循环变量i的值: 0 main的循环变量i的值: 1 main的循环变量i的值: 2 ... 有返回值的线程的循环变量i的值: 0 有返回值的线程的循环变量i的值: 1 ... 有返回值的线程的循环变量i的值: 99 main的循环变量i的值: 99 子线程的返回值:100 Process finished with exit code 0

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3