JavaWeb笔记02:多线程引入

进程操作系统资源分配的最小单位
线程操作系统调度的最小单位

多进程理解:一条流水线代表一个进程,要想提高效率,使用多进程,即增加多个流水线。
多线程理解:在一条流水线中增加多个工人,进而提高效率,但是一条流水线上的资源是有限的,即使用多线程也是有限制的。这里的资源指的是CPU资源,当线程达到一定数量后,将不会再增加效率。

1 进程与线程的区别:
  • 进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位)
  • 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,而线程是共享进程中的数据、地址空间
  • 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以 IPC(Inter-Process Communication,进程间通信)进行。
  • 多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
2 使用多线程计算多个累加和
public class web {
    static final int COUNT  =10;
    static final long NUMBER = 10000;
    static long sum(){
        long r=0;
        for(long i=0;i<NUMBER;i++){
            r+=i;
        }
        return r;
    }
    static void 单线程(){
        long b = System.nanoTime();
        for (int i = 0; i < COUNT; i++) {
            System.out.println(sum());
        }
        long e = System.nanoTime();

        double s = (e - b) / 1000_000_000.0;
        System.out.printf("单线程,运行时间: %f%n", s);
    }
    //定义一个类,继承Thread,用来创建线程
    //run()方法就是该线程要执行的任务
    static class SumThread extends  Thread{
        @Override
        public void run() {
            System.out.println(sum());
        }
    }
    static  void 多线程() throws InterruptedException {
        long b=System.nanoTime();
        // 因为当前也处于一个线程中,所以,只需要再创建 COUNT - 1 个线程就够了
        Thread[] threads = new Thread[COUNT-1];
        for (int i=0;i<COUNT-1;i++){
            // 创建的线程执行的就是上面定义的类中的 run 方法
            threads[i] = new SumThread();
            threads[i].start();
        }
        // 剩下的一次,当前线程来计算
        System.out.println(sum());
        //等待其他线程结束
        for(int i=0;i<COUNT-1;i++){
            threads[i].join();
        }
        long e = System.nanoTime();
        double time = (e-b)/1000_000_000;
        System.out.printf("多线程运行时间:%f%n",time);
    }

    public static void main(String[] args) throws InterruptedException {
        单线程();
        System.out.println("+++++++++++++++++++++++");
        多线程();
    }
}

首先要定义一个类,继承Thread,该类用来创建线程,其中,run()方法中的内容就是该线程要执行的任务。

   static class SumThread extends  Thread{
        @Override
        public void run() {
            System.out.println(sum());
        }
    }

使用new SumThread()创建一个线程,调用start()方法启动该线程。join()用来等待某线程结束。

  for (int i=0;i<COUNT-1;i++){
            // 创建的线程执行的就是上面定义的类中的 run 方法
            threads[i] = new SumThread();
            threads[i].start();
        }
      //等待其他线程结束
        for(int i=0;i<COUNT-1;i++){
            threads[i].join();
        }

程序计时 nanoTime()返回的是纳秒nanoseconds:

  * @return the current value of the running Java Virtual Machine's
     *         high-resolution time source, in nanoseconds
    public static native long nanoTime();

注意:

  • 除了创建的线程之外,创建线程的本身也属于一个线程。
  • 当运算量较小时,反而多线程的运行时间要高于单线程。这是因为创建线程也是需要时间的。
3. 使用多线程解决IO阻塞问题

如果使用单线程进行读取用户输入时,用户操作时会发生阻塞。而多线程可以解决该问题。

public class test2 {
    static int fib(int n){
        if(n<2){
            return 1;
        }
        return fib(n-1)+fib(n-2);
    }
	//定义一个使用线程的内部类
    static class FibThread extends  Thread{
        int n;
        FibThread(int n){
            this.n=n;
        }
        @Override
        public void run() {
            System.out.printf("fib(%d) = %d%n",n,fib(n));
        }
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.print("请输入要计算的数: ");
            int n = scanner.nextInt();
            scanner.nextLine();
            //System.out.println(fib(n));
            new FibThread(n).start();
        }
    }
}

如果是单线程,当计算很大的数时,单线程会堵塞在计算fib(n)这里,直到计算完成才继续向下执行,而使用多线程则完全没有这种问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值