论单线程和多线程

在我们日常的项目开发过程中进场会接触到单线程或多线程的知识,那么到底多线程好还是单线程好呢?单线程和多线程的区别又是什么呢?下面我们来看看它们的区别以及优缺点分析及实例展示。

一、线程的含义

线程:每一个任务称为一个线程,线程不能独立的存在,它必须是进程的一部分

单线程:般常见的Java应用程序都是单线程的,比如运行helloworld的程序时,会启动jvm进程,然后运行main方法产生线程,main方法也被称为主线程.

多线程:同时运行一个以上线程的程序称为多线程程序,多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。

二、单线程

每个正在运行的程序(即进程),至少包括一个线程,这个线程叫主线程

主线程在程序启动时被创建,用于执行main函数

只有一个主线程的程序,称作单线程程序

主线程负责执行程序的所有代码(UI展现以及刷新,网络请求,本地存储等等)。这些代码只能顺序执行,无法并发执行。

三、多线程

拥有多个线程的程序,称作多线程程序。

iOS允许用户自己开辟新的线程,相对于主线程来讲,这些线程,称为子线程

可以根据需要开辟若干子线程

子线程和主线程都是独立的运行单元,各自的执行互不影响,因此能够并发执行

四、单线程与多线程的区别

单线程程序:只有一个线程,代码顺序执行,容易出现代码阻塞。

多线程程序:有多个线程,线程间独立运行,能有效地避免代码阻塞,并且提高程序的运行性能。

五、单线程与多线程的优缺点分析

多线程优缺点:
  同步应用程序的开发比较容易,但由于需要在上一个任务完成后才能开始新的任务,所以其效率通常比多线程应用程序低。如果完成同步任务所用的时间比预计时间长,应用程序可能会不响应。多线程处理可以同时运行多个过程。

例如:文字处理器应用程序在您处理文档的同时,可以检查拼写(作为单独的任务)。由于多线程应用程序将程序划分成独立的任务,因此可以在以下方面显著提高性能:

多线程技术使程序的响应速度更快,因为用户界面可以在进行其他工作的同时一直处于活动状态。

当前没有进行处理的任务可以将处理器时间让给其他任务。

占用大量处理时间的任务可以定期将处理器时间让给其他任务。

可以随时停止任务。

可以分别设置各个任务的优先级以优化性能。

是否需要创建多线程应用程序取决于多个因素。在以下情况下,最适合采用多线程处理:

耗时或大量占用处理器的任务阻塞用户界面操作。

各个任务必须等待外部资源(如远程文件或 INTERNET 连接)。

例如:用于跟踪 WEB 页上的链接并下载满足特定条件的文件的 INTERNET 应用程序“ROBOT”。这种应用程序可以依次同步下载各个文件,也可以使用多线程同时下载多个文件。多线程方法比同步方法的效率高很多,因为即使在某些线程中远程 WEB 服务器的响应非常慢,也可以下载文件。

坏处:增加了调度和管理的开销,带来了一些不确定性,需要复杂的同步机制,避免死锁等等。

好处:一定程度上提高响应速度,在多核的情况下还是更能充分利用CPU资源的。

单线程优缺点:
  单线程的也就是程序执行时,所跑的程序路径(处理的东西)是连续顺序下来的,必须前面的处理好,后面的才会执行到。

由于时间片很短,这样给用户的感觉是同时有好多线程在执行。但是线程切换是有代价的,因此如果采用多进程,那么就需要将线程所隶属的该进程所需要的内存进行切换,这时间代价是很多的。而线程切换代价就很少,线程是可以共享内存的。所以采用多线程在切换上花费的比多进程少得多。但是,线程切换还是需要时间消耗的,所以采用一个拥有两个线程的进程执行所需要的时间比一个线程的进程执行两次所需要的时间要多一些。即采用多线程不会提高程序的执行速度,反而会降低速度,但是对于用户来说,可以减少用户的响应时间。上述结果只是针对单CPU,如果对于多CPU或者CPU采用超线程技术的话,采用多线程技术还是会提高程序的执行速度的。因为单线程只会映射到一个CPU上,而多线程会映射到多个CPU上,超线程技术本质是多线程硬件化,所以也会加快程序的执行速度。

线程相对于进程的优点:

1、开销小

2、资源共享性好。

线程相对于进程的缺点:

1、共享资源需要耗费一定的锁资源,同步相对复杂。

2、一个线程崩溃可能导致整个进程崩溃,这个当然是自己的应用程序有问题

六、单线程与多线程实例展示

单线程实例

public class SingleThread {
    public static void main(String[] args){
        Thread thread = Thread.currentThread(); //获取当前运行的线程对象
        thread.setName("单线程"); //线程重命名
        System.out.println(thread.getName()+"正在运行");
        for(int i=0;i<10;i++){
            System.out.println("线程正在休眠:"+i);
            try {
                thread.sleep(1000); //线程休眠,延迟一秒
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("线程出错");
            }
        }
    }
}

多线程实例
  
  注意:多线程有两种实现方式,一种是继承Thread类,另一种是实现Runnable接口。
  
  继承Thread类实现多线程

public class TestThread {
    public static void main(String[] args){
         Thread n1 = new ExtendThread("n1",3000); //使用上转对象创建线程,并构造线程名字和线程休眠时间
         Thread n2 = new ExtendThread("n2",6000); 
         Thread n3 = new ExtendThread("n3",9000); 
         n1.start(); //启动线程并调用run方法
         n2.start();
         n3.start();
    }
}
class ExtendThread extends Thread{ //继承Thread的类
    String name;
    int time;
    public ExtendThread(String name, int time) { //构造线程名字和休眠时间
        this.name=name;
        this.time=time;
    }   
    public void run(){ //重写Thread类的run方法
        try{
            sleep(time); //所有线程加入休眠
        }
        catch(InterruptedExceptione){
            e.printStackTrace();
            System.out.println("线程中断异常");
        }
        System.out.println("名称为:"+name+",线程休眠:"+time+"毫秒"); 
    }
}

实现Runnable接口的多线程

public class RunnableThread {
    public static void main(String[] args){
        Runnable rb1=new ImplRunnable("rb1",3000); //Runnable接口必须依托Thread类才能创建线程
        Thread n1=new Thread(rb1); //Runnable并不能调用start()方法,因为不是线程,所以要用Thread类加入线程
        Runnable rb2=new ImplRunnable("rb2",6000);
        Thread n2=new Thread(rb2);
        Runnable rb3=new ImplRunnable("rb3",9000);
        Thread n3=new Thread(rb3);
         
        n1.start(); //启动线程并调用run方法
        n2.start();
        n3.start();
    }
}
class ImplRunnable implements Runnable{ //继承Runnable接口的类
    String name;
    int time;   
    public ImplRunnable(String name, int time) { //构造线程名字和休眠时间
        this.name = name;
        this.time = time;
    }
 
    @Override
    public void run() { //实现Runnable的run方法
        try{
            Thread.sleep(time); //所有线程加入休眠
        }
        catch(InterruptedException e){
            e.printStackTrace();
            System.out.println("线程中断异常");
        }
        System.out.println("名称为:"+name+",线程休眠:"+time+"毫秒");
    }
}

了解更多关注我哟!!!

发布了236 篇原创文章 · 获赞 87 · 访问量 7203

猜你喜欢

转载自blog.csdn.net/weixin_45743799/article/details/104134916