ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

线程常见问题

2021-07-27 21:04:59  阅读:105  来源: 互联网

标签:常见问题 run Thread Runnable 线程 多线程 方法


一.什么是多线程

线程是指程序在运行的过程中,能够执行程序代码的一个执行单元。

Java语言中,线程有五种状态:新建、就绪、运行、阻塞及死亡。


二.线程与进程的区别?

 进程是指一段正在执行的程序。而线程有时也被称为轻量级进程,它是程序执行的最小单元,一个进程可以拥有多个线程,各个线程之间共享程序的内存空间(代码段、数据段、堆空间)及一些进程级


三、为什么要使用多线程?
        【1】提高执行效率,减少程序的响应时间。因为单线程执行的过程只有一个有效的操作序列,如果某个操作很耗时(或等待网络响应),此时程序就不会响应鼠标和键盘等操作,如果使用多线程,就可以将耗时的线程分配到一个单独的线程上执行,从而使程序具备更好的交互性。
        【2】与进程相比,线程的创建和切换开销更小。因开启一个新的进程需要分配独立的地址空间,建立许多数据结构来维护代码块等信息,而运行于同一个进程内的线程共享代码段、数据段、线程的启动和切换的开销比进程要少很多。同时多线程在数据共享方面效率非常高。
        【3】目前市场上服务器配置大多数都是多CPU或多核计算机等,它们本身而言就具有执行多线程的能力,如果使用单个线程,就无法重复利用计算机资源,造成资源浪费。因此在多CPU计算机上使用多线程能提高CPU的利用率。
        【4】利用多线程能简化程序程序的结构,是程序便于理解和维护。一个非常复杂的进程可以分成多个线程来执行。
 


四、同步与异步有什么区别?
        在多线程的环境中,通常会遇到数据共享问题,为了确保共享资源的正确性和安全性,就必须对共享数据进行同步处理(也就是锁机制)。对共享数据进行同步操作(增删改),就必须要获得每个线程对象的锁(this锁),这样可以保证同一时刻只有一个线程对其操作,其他线程要想对其操作需要排队等候并获取锁。当然在等候队列中优先级最高的线程才能获得该锁,从而进入共享代码区。
        Java语言在同步机制中提供了语言级的支持,可以通过使用synchronize关键字来实现同步,但该方法是以很大的系统开销作为代价的,有时候甚至可能造成死锁,所以,同步控制并不是越多越好,要避免所谓的同步控制。实现同步的方法有两种:①同步方法(this锁)。②同步代码块(this锁或者自定义锁)当使用this锁时,就与同步方法共享同一锁,只有当①释放,②才可以使用。同时,同步代码块的范围也小于同步方法,建议使用,相比之下能够提高性能。 

五、如何实现java多线程?
         Java虚拟机允许应用程序并发地运行多个线程,在Java语言中实现多线程的方法有三种,其中前两种为常用方法:

【1】继承Thread类,重写run()方法
         Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且启动线程的唯一方法就是通过Thread类的start()方法,start()方法是一个本地(native)方法,它将启动一个新的线程,并执行run()方法(执行的是自己重写了Thread类的run()方法),同时调用start()方法并不是执行多线程代码,而是使得该线程变为可运行态(Runnable),什么时候运行多线程代码由操作系统决定。 
class MyThread extends Thread{//创建线程类
    public void run(){
       System.out.println("Thread Body");//线程的函数体
    }
}
 
public class Test{
   public static void main(String[] args){
     MyThread thread = new Thread
     thread.run();//开启线程
   }
}

【2】实现Runnable接口,并实现该结构的run()方法
        1)自定义实现Runnable接口,实现run()方法。
        2)创建Thread对象,用实现Runnable接口的对象作为参数实例化该Thread对象。
        3)调用Thread的start()方法。 
class MyThread implements Runnable{
   pulic void run(){
      System.out.println("Thread Body");
   }
}
 
public class Test{
  public static void main(String[] args){
     MyThread myThread = new MyThread;
     Thread thread = new Thread(myThread);
     thread.start();//启动线程
  }
}

其实,不管是哪种方法,最终都是通过Thread类的API来控制线程。

【3】实现Callable接口,重写call()方法
       Callable接口实际是属于Executor框架中的功能类,Callable结构与Runnable接口的功能类似,但提供了比Runnable更强大的功能,主要体现在如下三点:
        1)Callable在任务结束后可以提供一个返回值,Runnable无法提供该功能。
        2)Callable中的call()方法可以跑出异常,而Runnable中的run()不能跑出异常。
        3)运行Callable可以拿到一个Future对象,Future对象表示异步计算的结果,它提供能了检查计算是否完成的方法。由于线程输入异步计算模型,因此无法从别的线程中得到函数的返回值,在这种情况下,就可以使用Future来监控目标线程来调用call()方法的情况,当调用Future的get()方法以获取结果时,当前线程会阻塞,直到目标线程的call()方法结束返回结果。 
public class CallableAndFuture{
   //创建线程类
   public static class CallableTest implements Callable{
     public String call() throws Exception{
        return "Hello World!";
     }
   }
   public static void main(String[] args){
     ExecutorService threadPool = Executors.newSingleThreadExecutor();
     Future<String> future = threadPool.submit(new CallableTest());
     try{
          System.out.println("waiting thread to finish");
          System.out.println(future.get());
        }catch{Exception e}{
          e.printStackTrace
        }
   }
}

   建议:当需要实现多线程时,一般推荐使用Runnable接口方式,因为Thread类定义了多种方法可以被派生类使用或重写,但是只有run()方法必须被重写,在run()方法中实现这个线程的主要功能,这当然也是实现Runnable接口所需的方法。再者,我们很多时候继承一个类是为了去加强和修改这个类才去继承的。因此,如果我们没有必要重写Thread类中的其他方法,那么通过继承Thread类和实现Runnable接口的效果是相同的,这样的话最好还是使用Runnable接口来创建线程。 
六、run()方法与start()方法有什么区别?

        通常,系统通过调用线程类的start()方法启动一个线程,此时该线程处于就绪状态,而非运行状态,也就意味着这个线程可以别JVM调用执行,执行的过程中,JVM通过调用想成类的run()方法来完成实际的操作,当run()方法结束后,线程也就会终止。
       如果直接调用线程类的run()方法,就会被当做一个普通函数调用,程序中仍然只有一个主程序,也就是说start()方法能够异步调用run()方法,但是直接调用run()方法却是同步的,也就无法达到多线程的目的。

 

标签:常见问题,run,Thread,Runnable,线程,多线程,方法
来源: https://blog.csdn.net/weixin_60158745/article/details/119086264

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有