原创

Java并发编程(一)-什么是并发和创建线程的方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lyhkmm/article/details/79317655

什么是并发

        并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
       Java是一种多线程编程语言,我们可以使用Java来开发多线程程序。 多线程程序包含两个或多个可同时运行的部分,每个部分可以同时处理不同的任务,从而能更好地利用可用资源,特别是当您的计算机有多个CPU时。多线程使您能够写入多个活动,可以在同一程序中同时进行操作处理。根据定义,多任务是当多个进程共享,如CPU处理公共资源。 多线程将多任务的概念扩展到可以将单个应用程序中的特定操作细分为单个线程的应用程序。每个线程可以并行运行。 操作系统不仅在不同的应用程序之间划分处理时间,而且在应用程序中的每个线程之间划分处理时间。多线程能够在同一程序同中,进行多个活动的方式进行写入。

线程的生命周期

       线程在其生命周期中经历各个阶段。 例如,线程诞生,启动,运行,然后死亡。以下是线程生命周期的阶段

   新线程(New)

      新线程在新的状态下开始其生命周期。直到程序启动线程为止,它保持在这种状态。它也被称为出生线程。

   可运行(Runnable)

      新诞生的线程启动后,该线程可以运行。状态的线程被认为正在执行其任务。

   等待(Waiting)

      有时,线程会转换到等待状态,而线程等待另一个线程执行任务。 只有当另一个线程发信号通知等待线程才能继续执行时,线程才转回到可运行状态。

   定时等待(Timed Waiting)

      可运行的线程可以在指定的时间间隔内进入定时等待状态。 当该时间间隔到期或发生等待的事件时,此状态的线程将转换回可运行状态。

   终止(Dead)

      可执行线程在完成任务或以其他方式终止时进入终止状态。

线程优先级

       每个Java线程都有一个优先级,可以帮助操作系统确定安排线程的顺序。Java线程优先级在MIN_PRIORITY(常数为1)和MAX_PRIORITY(常数为10)之间的范围内。 默认情况下,每个线程都被赋予优先级NORM_PRIORITY(常数为5)。具有较高优先级的线程对于一个程序来说更重要,应该在低优先级线程之前分配处理器时间。 然而,线程优先级不能保证线程执行的顺序,并且依赖于平台。

创建线程的两种方式

      一种是通过继承Thread,另一种是通过实现Runnable接口。查看JDK里的Thread类,可以看到Thread实际上是实现Runnable接口:

    public class Thread implements Runnable

而Runnable只有一个抽象方法:

    @FunctionalInterface
    public interface Runnable {
        public abstract void run();
    }

      Runnable相当于一个作业,而Thread才是真正的处理线程,我们需要的只是定义这个作业,然后将作业交给线程去处理。
      在实际项目开发中,实现Runnable接口比继承Thread类所具有的优势:

  1. 适合多个相同的程序代码的线程去处理同一个资源
  2. java不允许多继承,因此实现了Runnable接口的类可以再继承其他类。而继承了Thread就不能再继承其他类。
  3. 增加程序的健壮性,代码可以被多个线程共享,代码和数据独立

通过扩展Thread类创建一个线程

      需要覆盖Thread类中的run()方法。 该方法为线程提供了一个入口点,可以把完整的业务逻辑放在此方法中。当创建了一个Runnable线程对象,可以通过调用start()方法启动它,该方法执行对run()方法的调用。 以下是一个简单的语法start()方法:

    class ThreadDemo extends Thread {
        private String threadName;
        ThreadDemo( String name) {
            threadName = name;
            System.out.println("创建线程:" +  threadName );
        }
        @Override
        public void run() {
            System.out.println("运行线程:" +  threadName );
            try {
                for(int i = 4; i > 0; i--) {
                    System.out.println(threadName + ":正在执行第" + i+"循环");
                    // Let the thread sleep for a while.
                    Thread.sleep(50);
                }
            }catch (InterruptedException e) {
                System.out.println("Thread " +  threadName + " interrupted.");
            }
            System.out.println("结束线程: " +  threadName);
        }
    }
    public class TestThread {
        public static void main(String args[]) {
            Thread T1 = new ThreadDemo( "Thread-1");
            T1.start();
            Thread T2 = new ThreadDemo( "Thread-2");
            T2.start();
        }
    }

通过实现Runnable接口创建一个线程

      需要实现由Runnable接口提供的run()方法。 该方法为线程提供了一个入口点,可将把完整的业务逻辑放在此方法中。当创建了一个Thread线程对象,可以通过调用start()方法启动它,该方法执行对run()方法的调用。 以下是一个简单的语法start()方法 :

    class RunnableDemo implements Runnable {
        private String threadName;
        RunnableDemo( String name) {
            threadName = name;
            System.out.println("创建线程:" +  threadName );
        }
        @Override
        public void run() {
            System.out.println("运行线程:" +  threadName );
            try {
                for(int i = 4; i > 0; i--) {
                    System.out.println(threadName + ":正在执行第" + i+"循环");
                    // Let the thread sleep for a while.
                    Thread.sleep(50);
                }
            }catch (InterruptedException e) {
                System.out.println("Thread " +  threadName + " interrupted.");
            }
            System.out.println("结束线程: " +  threadName);
        }
    }
    public class TestRunnable {
        public static void main(String args[]) {
            RunnableDemo R1 = new RunnableDemo( "Thread-1");
            //new Thread是实现Runnable接口的类的实例
            new Thread(R1).start();
            RunnableDemo R2 = new RunnableDemo( "Thread-2");
            new Thread(R2).start();
        }
    }

      实现Runnable接口的对象需要Thread类的构造函数实例化一个Thread对象后调用start()方法运行。这里需要注意的是:
      start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
      run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。
      在实际项目中通常是使用线程池来管理项目。

正文到此结束
Loading...