java系列之多线程(线程)

208 阅读5分钟

一、线程

1.何为线程?

这里首先接用下百度百科:

线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。(baike.baidu.com/item/线程/103…

由此我们可以看出来,线程是操作系统运行的最小单位,而进程则是可以包含多个线程。比如操作系统中的QQ,开启之后对于操作系统而言是一个进程,而为了我们能够收发消息和账户安全之类的功能,又会存在多个线程帮助其执行不同的任务。

让我们再来看一下Thread类的注释说明:

  • A thread is a thread of execution in a program.The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.(1.线程是程序的可执行部分,JVM允许一个程序存在多个线程同时运行的情况)
  • Every thread has a priority.
  • Threads with higher priority are executed in preference to threads with lower priority. (2.线程存在优先级,高优先级的线程相比低优先级的线程会先被执行)
  • Each thread may or may not also be marked as a daemon. When code running in
  • some thread creates a new Thread object, the new
  • thread has its priority initially set equal to the priority of the
  • creating thread, ((3.当一个线程开启另外一个线程的时候,新线程一般会具有和创建它的线程相同的优先级。)
  • and is a daemon thread if and only if the
  • creating thread is a daemon.(4.而且如果创建新线程的这个线程如果是守护线程,那么这个被创建的线程也会是守护线程)
  • When a Java Virtual Machine starts up, there is usually a single
  • non-daemon thread (which typically calls the method named
  • main of some designated class).(5.一般而言,当JVM启动的时候,通常会创建一个由称作main方法的单个非守护线程。)
  • The Java Virtual Machine continues to execute threads until either of the following occurs:(6.发生以下情况,JVM会停止线程的执行:)
  •   The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.(当发生对Runtime的exit方法调用,而且security manager同意退出,则会停止当前线程的继续执行)
  •   All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.(所有线程都不是守护线程,而且通过调用run方法执行完成或者是抛出异常导致线程停止)

其实看完上面部分我们应该对java的thread类有了一定的理解:JVM运行起来本身对于操作系统而言,也是一个进程。它同样也支持开启多线程。另外可能还会有几个名词会有些疑惑:比如什么是priority和daemon,如何设置和怎么用呢?这部分咱们不要着急,在后续咱们再详谈。 说到线程,那我们肯定是比较关心在java中如何创建一个线程呢?下面就让我们继续看下Thread类的注释。

2.如何创建一个线程

There are two ways to create a new thread of execution. (创建一个线程存在两个方式)

  • One is to declare a class to be a subclass of Thread. (声明一个类是Thread类的子类)
  • This subclass should override the run method of class Thread.(这个子类需要覆盖父类Thread的Run方法)
  • An instance of the subclass can then be allocated and started.(这样这个子类的实例可以被创建和开启线程运行)
  • For example, a thread that computes primes larger than a stated value could be written as follows:(子类的例子)

  • class PrimeThread extends Thread {
    
  •     long minPrime;
    
  •     PrimeThread(long minPrime) {
    
  •         this.minPrime = minPrime;
    
  •     }
    
  •     public void run() {
    
  •         // compute primes larger than minPrime
    
  •          . . .
    
  •     }
    
  • }
    

  • The following code would then create a thread and start it running:(创建子类和运行线程)
  • PrimeThread p = new PrimeThread(143);
    
  • p.start();
    
  • The other way to create a thread is to declare a class that implements the Runnable interface. (另外一个创建线程的方式是声明一个类实现了Runnable接口)
  • That class then implements the run method. (这个类实现run方法)
  • An instance of the class can then be allocated, passed as an argument when creating Thread, and started. (首先创建这个类的实例,然后将其作为参数,创建一个Thread类,然后运行线程)
  • The same example in this other style looks like the following:(实现接口类的例子)

  • class PrimeRun implements Runnable {
    
  •     long minPrime;
    
  •     PrimeRun(long minPrime) {
    
  •         this.minPrime = minPrime;
    
  •     }
    
  •     public void run() {
    
  •         // compute primes larger than minPrime
    
  •          . . .
    
  •     }
    
  • }
    

  • The following code would then create a thread and start it running:(创建类和创建线程后运行线程的例子)
  • PrimeRun p = new PrimeRun(143);
    
  • new Thread(p).start();
    

由此,我们可以知道两种方式可以创建出一个线程:

1.声明一个类是Thread类的子类

2.声明一个类实现了Runnable接口

其实我们可以看一下Thread类:

public class Thread implements Runnable

也就是说,其实Thread类也是实现了Runnable的接口,只不过,Thread类的run方法是对target对象的run方法实现了调用:


   @Override
   public void run() {
   if (target != null) {
            target.run();
        }
    }
  
  Thread类会在构造方法中调用一个叫做init的方法,实现对target对象的赋值,比如咱们使用传入Runnable的构造方法:
  

    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
      ...........
        this.target = target;
      ...........
    }
  
 所以从本质上而言,其实都是Runnable来实现线程的运行。
对于线程的基本信息咱们先介绍到这里。