JAVA

    技术2022-07-12  97

    JAVA实现多线程的四种方法

    Thread类Runnable接口Callable接口使用线程池

    Thread类

    继承Thread类,然后重写run方法(其实Thread类本身也实现了Runnable接口)

    public class Thread1 extends Thread{ public static void main(String[] args) throws InterruptedException { //新建对象 Thread1 xc = new Thread1(); //启动线程 xc.start(); //打印线程的名称 System.out.println(xc.getName()); //返回对当前正在执行的线程对象的引用然后设置线程的优先级为最大。 xc.currentThread().setPriority(MAX_PRIORITY); //当前java程序的主线程 for (int i = 1; i < 100; i++) { System.out.println("主线程"+i); } } @Override public void run() { for(int i=1;i<=100;i++){ System.out.println("i:"+i); } } }

    首先继承Thread类,然后重写run方法.在run方法中写入线程运行的代码. 然后在main方法中新建线程对象调用start方法启动线程.设置xc.currentThread().setPriority(MAX_PRIORITY);将获取到的线程对象优先级设为最大.然后我们看运行结果 我们能看到被设置线程优先级为最大值的线程首先执行了,然后才是主线程抢到了执行权,在下一个线程… 我们发现这两个线程都轮番执行一遍,事实是这样吗,让我们在运行一遍 结果出来,很明显刚刚只是巧合 ,首先还是被设置线程优先级为最大值的线程首先执行了,只执行了一次,然后才是主线程抢到了执行权,但是主线程执行了很多次才轮到另一个线程执行,所以说这个执行次数不是固定的,主要取决于哪个线程能更快抢到执行权,这也跟电脑配置有关系,cpu越好,连续同一个线程执行的几率就会越高;(详情请看上一篇博客)

    Runnable接口

    实现Runnable接口,重写run方法 不论创建多少个线程,只需要创建一个Runnable接口实现类的对象

    其实我们去看Thread类,其内部就是实现了Runnable接口 实现:

    public class xiancheng implements Runnable{ public static void main(String[] args) { xiancheng xc = new xiancheng(); Thread t = new Thread(xc); t.start(); for(int i = 1; i < 100; i++) { System.out.println("主线程"+i); } } @Override public void run() { for(int i = 1; i < 100; i++) { System.out.println("i:"+i); } } }

    实现Runnable接口,重写run方法,然后新建Thread对象传入实现Runnable接口的类对象然后调用start方法启动

    Callable接口

    实现Callable接口,重写call方法(有返回值)   自定义类实现Callable接口时,必须指定泛型,该泛型即返回值的类型   每次创建一个新的线程,都要创建一个新的Callable接口的实现类、   如何启动线程? (1)创建一个Callable接口的实现类的对象 (2)创建一个FutureTask对象,传入Callable类型的参数 public FutureTask(Callable callable){……} (3)调用Thread类重载的参数为Runnable的构造器创建Thread对象 将FutureTask作为参数传递 public class FutureTask implements RunnableFuture

    public interface RunnableFuture extends Runnable, Future 调用FutureTask类的get()方法获取返回值

    public class MyThread { public static void main(String ards[]) throws InterruptedException, ExecutionException{ for(int i=0;i<10;i++){ Callable<Integer> implCallable = new ImplCallable(); FutureTask<Integer> futureTask = new FutureTask<Integer>(implCallable); new Thread(futureTask).start(); System.out.println(Thread.currentThread().getName()+"----"+futureTask.get()); } System.out.println(Thread.currentThread().getName()); } } class ImplCallable implements Callable<Integer>{ @Override public Integer call() throws Exception { int result = 0; for(int i=0;i<10;i++){ result += i; } System.out.println(Thread.currentThread().getName()); return result; } }

    使用线程池

    Executors类

    线程池,跟数据库连接池类似,避免了线程的创建和销毁造成的额外开销 Executor 负责现成的使用和调度的根接口 ExecutorService 线程池的主要接口 ThreadPoolExecutor 线程池的实现类 ScheduledExecutorService 接口,负责线程的调度

    public class ThreadPool { public static void main(String[] args){ //使用Executors工具类中的方法创建线程池 ExecutorService pool = Executors.newFixedThreadPool(5); ThreadPoolDemo demo = new ThreadPoolDemo(); //为线程池中的线程分配任务,使用submit方法,传入的参数可以是Runnable的实现类,也可以是Callable的实现类 for(int i=1;i<=5;i++){ pool.submit(demo); } //关闭线程池 //shutdown : 以一种平和的方式关闭线程池,在关闭线程池之前,会等待线程池中的所有的任务都结束,不在接受新任务 //shutdownNow : 立即关闭线程池 pool.shutdown(); } } class ThreadPoolDemo implements Runnable{ /**多线程的共享数据*/ private int i = 0; @Override public void run() { while(i<=50){ System.out.println(Thread.currentThread().getName()+"---"+ i++); } } } public class ThreadPool2 { public static void main(String args[]){ ExecutorService executorService = Executors.newFixedThreadPool(5); for(int i=0;i<5;i++){ Future<Integer> future = executorService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { int result = 0; for(int i=0;i<=10;i++){ result += i; } return result; } }); try { System.out.println(Thread.currentThread().getName()+"--"+future.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } executorService.shutdown(); } }

    java实现多线程的四种方法就到这,88了

    Processed: 0.015, SQL: 10