• java中创建多线程的方式


    在java中比较常用的有三种创建多线程的方式。

    方式一:继承Thread类,要重写run方法。

    在MyThread类

    1 public class MyThread extends Thread {
    2     @Override
    3     public void run() {
    4         for (int i = 0; i < 100    ; i++) {
              //获取线程名称
    5 System.out.println(getName()+":"+i); 6 } 7 super.run(); 8 } 9 }

    测试类:

     1 public class MyThreadDemo {
     2     public static void main(String[] args) {
     3         MyThread my1 = new MyThread();
     4         MyThread my2 = new MyThread();
     5         my1.setName("张飞");
     6         my2.setName("关羽");
     7         
     8         my1.setDaemon(true);
     9         //开启线程
    10         my1.start();
    11         my2.start();
    12         //设置主线程名称
    13         Thread.currentThread().setName("刘备");
    14         
    15         for (int i = 0; i < 5; i++) {
    16             System.out.println(Thread.currentThread().getName()+":"+i);
    17         }
    18     }
    19 }

    常用方法:

    public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
    当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用

    public static void sleep(long millis,int nanos) 在指定的毫秒数内让当前正在执行的线程休眠

    public static void yield():暂停当前正在执行的线程对象,并执行其他线程。让多个线程的执行更和谐,但是不能靠它保证一人一次。
    public final void join():等待该线程终止。 该线程终止才能执行其他线程
    优先级
    public final int getPriority():返回线程对象的优先级
    public final void setPriority(int newPriority):更改线程的优先级
     线程默认优先级是5。
     程优先级的范围是:1-10。
     线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。

    这里再提一句:start和run方法有什么区别:run方法就是执行括号里的代码  start方法是首先启动了线程,然后由jvm调用run方法。

    方式二

    实现Runnable接口,也要重写run方法。创建Thread对象,将Runnable作为参数传递。

     1 //测试Runnable
     2     public static void testRunnable(){
     3         //创建Runnable对象
     4         Runnable r = new Runnable() {
     5             
     6             @Override//run()方法没有返回值,只能通过try抛出异常
     7             public void run() {
     8                 System.out.println("当前线程的名字是:"+Thread.currentThread().getName());
     9                 try {
    10                     Thread.sleep(2000);
    11                 } catch (InterruptedException e) {
    12                     // TODO: handle exception
    13                 }
    14             }
    15         };
    16         //Thread包装Runnable
    17         Thread t = new Thread(r);
    18         t.start();
    19     }

    方式三

    实现Callable接口。在展示Demo之前,说一说实现这个接口需要用到的类和接口。

    ExecutorService(线程池):接口,它的超级接口是Executor

    下面这些是返回ExecutorService对象的方法。

     * public static ExecutorService newCachedThreadPool()   创建corePoolSize为0,最大线程数为整型的最大数,线程   keepAliveTime为1分钟,缓存任务的队列为SynchronousQueue的线程池。

    * public static ExecutorService newFixedThreadPool(int nThread)   创建固定大小的线程池

    * public static ExecutorService newSingleThreadExecutor()    创建大小为1的固定线程池

     

    可以执行Runnable对象或者Callable对象代表的线程。

      Future<?> submit(Runnable task)

    <T> Future<T> submit(Callable<T> task)

     

    Executors(类):提供了用于此包中所提供的执行程序服务的工厂方法。也就是说可以用它来创建线程池。

     

    Future(接口),API解释:

    Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。说白了就是获取Callable返回值的对象。

     

    FutureTask(类):它实现的接口:Runnable Future<V> RunnableFuture<V>。

    构造方法:

    FutureTask(Callable<V> callable)

              创建一个 FutureTask,一旦运行就执行给定的 Callable。

    FutureTask(Runnable runnable, V result) 

              创建一个 FutureTask,一旦运行就执行给定的 Runnable,并安排成功完成时 get 返回给定的结果 。

     1 //测试Callable,可以通过throws抛出异常
     2     public static void testCallable() throws InterruptedException, ExecutionException{
     3         //创建对象
     4         Callable<Student> c = new Callable<Test.Student>() {
     5 
     6             @Override
     7             //call()方法可以有返回值,并且可以通过throws抛出异常
     8             public Student call() throws Exception {
     9                 System.out.println("当前线程的名称是:"+Thread.currentThread().getName());
    10                 Thread.sleep(2000);
    11                 return new Student("张飞", 30);
    12             }
    13         };
    14         //包装对象  第一种方法
    15         FutureTask<Student> ft = new FutureTask<Student>(c);
    16         
    17         try {
    18             //执行线程
    19             new Thread(ft).start();
    20             //获取结果
    21             System.out.println(ft.get().getName()+ft.get().getAge());
    22         } catch (Exception e) {
    23             e.printStackTrace();
    24         }
    25         
    26         //第二种方法
    27         //创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
    28         ExecutorService es =  Executors.newSingleThreadExecutor();
    30         //Executors  Executor  ExecutorService
    31         Future<Student> f = es.submit(new Callable<Student>() {
    32 
    33             @Override
    34             public Student call() throws Exception {
    35                 
    36                 return new Student("关羽", 33);
    37             }
    38         });
    39         System.out.println(f.get().getName() + f.get().getAge());
    40         
    41         
    42 
    43     }

     

     

     

  • 相关阅读:
    C# 面向对象之概念理解(2)
    Linux中常用常用常用快捷键
    shell基本脚本命令
    awk命令详解及应用技巧
    Windows(64位IIS)未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序
    基础知识(net)<3> virtural , new ,override
    WCF REST<2>: 消费WCF REST 服务
    智能表单(2):简单使用HtmlEditor
    智能表单(1) : 开源HtmlEditor介绍
    ASP.NET Web API <2> 跨域消费Web API(JSONP)
  • 原文地址:https://www.cnblogs.com/losedMemory/p/6212831.html
Copyright © 2020-2023  润新知