java多线程01(thread类线程创建线程池)

Rainy113      2022-04-24     241

关键词:

Java多线程(Thread类、线程创建、线程池)

第一章 多线程

1.1 多线程介绍

1.1.1 基本概念

  • 进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。
  • 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
  • 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程

1.1.2 单线程程序

- 从入口main到结束,一条路走到底
- 好处:没有安全隐患
- 缺点:效率低
- 解决缺点:让方法一同运行起来,为程序开启多个执行的路,每个执行的路,成为线程。
- 示例代码:
    ```
    public static void main(String[] args){
        add();
        remove();
        get();
        System.out.println(222);
    }

    public static void add(){
        // 一万次循环
    }
    public static void remove(){
    }
    public static void get(){
    }
    ```

1.1.3 深入理解多线程

  • CPU中央处理器
    • Inter AMD
    • Inter Core i7 6680M
    • 四核心,八线程
    • 执行多线程时,每个功能都可以单独执行,开启功能,对CPU开启新的执行路径。
    • 线程深入理解:每个功能对于CPU的独立执行路径,就是线程。
  • 网上下载一个软件:
    • 下载的流程:
    • 单线程下载:一次读取n个字节
      • 浏览器下载:(IE)写一个,读一个,写一个,读一个
    • 多线程下载:一次读取m*m个字节,多(m)个线程读取同一个文件
      • 迅雷:开启一个线程,读取其中的一部分,再开启一个线程再读取一部分,...

1.2 程序运行原理

  • 分时调度:
    • 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。
  • 抢占式调度:
    • 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

抢占式调度详解

大部分操作系统都支持多进程并发运行,现在的操作系统几乎都支持同时运行多个程序。比如:现在我们上课一边使用编辑器,一边使用录屏软件,同时还开着画图板, dos窗口等软件。此时,这些程序是在同时运行,”感觉这些软件好像在同一时刻运行着“。
实际上,CPU(中央处理器)使用抢占式调度模式在多个线程间进行着高速的切换。对于CPU的一个核而言,某个时刻,只能执行一个线程,而 CPU的在多个线程间切换速度相对我们的感觉要快,看上去就是在同一时刻运行。
其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高。

1.3 主线程

  • 代码示例:
public class Demo {
    public static void main(String[] args) {
        fun();
        System.out.println(Math.abs(-9));
    }
    public static void fun() {
        for(int i=0;i<10000; i++) {
            System.out.println(i);
        }
    }
}
  • 分析:
    • 程序:从上到下的执行过程
    • 在dos窗口中:java Demo
    • 启动JVM,运行Demo.main
    • JVM 运行方法main,操作系统开启线程
    • 对于CPU有了一个执行的路径,运行方法main路径,有个名字“main”
    • 主线程:
  • 思考:
    • 能否实现一个主线程负责执行其中一个循环,再由另一个线程负责其他代码的执行,最终实现多部分代码同时执行的效果?
    • 能够实现同时执行,通过Java中的多线程技术来解决该问题。

1.4 Thread类

  • 通过API中搜索,查到Thread类。通过阅读Thread类中的描述。Thread是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
java.lang
Class Thread
java.lang.Object 
    java.lang.Thread 

All Implemented Interfaces: 
Runnable 
Direct Known Subclasses: 
ForkJoinWorkerThread 

    线程是程序中执行的线程。 Java虚拟机允许应用程序同时运行多个执行线程。
    每个线程都有优先权。 具有较高优先级的线程优先于具有较低优先级的线程执行。 每个线程可能也可能不会被标记为守护进程。
    当在某个线程中运行的代码创建一个新的Thread对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护进程线程。

- 常用构造方法
Thread() 
    Allocates a new Thread object. 
Thread(Runnable target) 
    Allocates a new Thread object. 
Thread(Runnable target, String name) 
    Allocates a new Thread object. 
Thread(String name) 
    Allocates a new Thread object. 

- 常用方法
void run() 
    If this thread was constructed using a separate Runnable run object, then that Runnable object‘s run method is called; otherwise, this method does nothing and returns. 
static void sleep(long millis) 
    Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. 
void start() 
    Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread. 
  • 创建新执行线程有两种方法:
    • 一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。创建对象,开启线程。run方法相当于其他线程的main方法。

      class PrimeThread extends Thread {
          long minPrime;
          PrimeThread(long minPrime) {
              this.minPrime = minPrime;
          }
      
          public void run() {
              // compute primes larger than minPrime
              . . .
          }
      }
    • 另一种方法是声明一个实现 Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。

      class PrimeRun implements Runnable {
          long minPrime;
          PrimeRun(long minPrime) {
              this.minPrime = minPrime;
          }
      
          public void run() {
              // compute primes larger than minPrime
               . . .
          }
      }
  • 两种方法的区别;

1.5 创建新执行线程方法一:继承Thread类

  • 创建线程的步骤:
    1. 定义一个类继承Thread。
    2. 重写run方法。
    3. 创建子类对象,就是创建线程对象。
    4. 调用start方法,开启线程并让线程执行,同时还会告诉jvm去调用run方法。
public class SubThread extends Thread {
    @Override
    public void run() {
        for(int i=0; i<50; i++) {
            System.out.println("run方法中的变量:"+i);
        }       
    }
}

public class ThreadDemo {   
    public static void main(String[] args) {   // 1、JVM从入口main开始执行主线程,从CPU开启第一条线程路径,执行main()方法。
        SubThread subThread = new SubThread();    // 2、创建线程对象,相当于开启了一个新的线程,从CPU开启第二条线程路径,执行run()方法。
        subThread.start();   // 3、执行start方法时,调用run()方法,与main()方法同时要调用CPU,两个执行路径都会被CPU执行,CPU自己选择的权利,出现执行结果,随机性结果。
        for(int i=0; i<50; i++) {
            System.out.println("main方法中的变量:"+i);
        }
    }
}

1.5.1 继承Thread类原理

  • 思考1:线程对象调用 run方法和调用start方法区别?
    • 线程对象调用run方法不开启线程。仅是对象调用方法。线程对象调用start开启线程,并让jvm调用run方法在开启的线程中执行。
  • 思考2:我们为什么要继承Thread类,并调用其的start方法才能开启线程呢?
    • 继承Thread类:因为Thread类用来描述线程,具备线程应该有功能。
  • 思考3:那为什么不直接创建Thread类的对象呢?如下代码:
    Thread t1 = new Thread();t1.start();
    • 这样做没有错,但是该start调用的是Thread类中的run方法,而这个run方法没有做什么事情,更重要的是这个run方法中并没有定义我们需要让线程执行的代码。
  • 思考4:创建线程的目的是什么?
    • 是为了建立程序单独的执行路径,让多部分代码实现同时执行。也就是说线程创建并执行需要给定线程要执行的任务。
    • 对于之前所讲的主线程,它的任务定义在main函数中。自定义线程需要执行的任务都定义在run方法中。
  • 思考5:为什么要重写run方法
    • Thread类run方法中的任务并不是我们所需要的,只有重写这个run方法。既然Thread类已经定义了线程任务的编写位置(run方法),那么只要在编写位置(run方法)中定义任务代码即可。所以进行了重写run方法动作。

1.5.2 线程运行时的内存情况

  • 单线程:所有执行的方法都在一个栈中,后调用的方法先执行,执行结束后弹出;
  • 多线程:每调用一个线程,就分配一个栈区,例如:main和run方法分别属于不同的栈区,CPU执行时,随机选择执行一个栈区中的方法。

1.5.3 获取线程名字Thread类方法getName()

  • Java API 中

    String getName()  // 返回线程的名字 
    static Thread currentThread()  // 获取当前线程
  • 示例:
public class NameThread extends Thread {
    @Override
    public void run() {
        System.out.println(super.getName());  // 输出本线程的名字
    }
}

/*
 * 每个线程都有自己的名字
 * 运行方法main线程的名字是"main"
 * 其他线程也有名字,默认为"Thread-0","Thread-1", ...
 * 获得主线程的名字的方法:JVM开启主线程,运行方法main,主线程也是线程,是线程必然是Thread类的对象,Thread类中的静态方法:
 *  static Thread currentThread() 返回正在执行的线程对象
 *  该对象调用getName方法,获取线程名字
 */
public class ThreadDemo2 {
    public static void main(String[] args) {
        NameThread nameThread = new NameThread();
        nameThread.start();
        
        // 获取主线程的线程名
        System.out.println(Thread.currentThread().getName());
    }
}

1.5.3 设置线程名字Thread类方法

  • Java API 中

    Thread(String name)  // 分配一个新的名字为name的对象
    void setName(String name) // 改变线程的名字为name
  • 方法一:

// 在主线程中
NameThread nameThread = new NameThread();
nameThread.setName("Thread线程名字");
  • 方法二:
// 在创建的线程类中的run方法中,调用Thread父类构造函数
super("Thread线程名字");

1.5.4 Thread类方法sleep()

  • 位置:可以写在main方法中,也可以写在Thread类中。
  • 代码:
public class SleepThread extends Thread{    
    @Override
    public void run() {
        for(int i=0; i<5; i++) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i);
        }
    }
}

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        SleepThread sleepThread = new SleepThread();
        sleepThread.start();
        Thread.sleep(2000);
    }
}

1.6 创建新执行线程方法二:实现Runnable接口

创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。
为何要实现Runnable接口,Runable是啥玩意呢?继续API搜索。
查看Runnable接口说明文档:Runnable接口用来指定每个线程要执行的任务。包含了一个 run 的无参数抽象方法,需要由接口实现类重写该方法。

  • Java API 中
// Runnable接口中只有一个run方法
// 方法摘要
void run() // 当使用实现接口Runnable的对象来创建线程时,启动该线程会导致在该单独执行的线程中调用该对象的run方法。

// 创建线程使用Thread类中的构造方法:
Thread(Runnable target)  // 分配一个线程对象,参数为Runnable接口实现类的对象
  • 创建线程的步骤。
    1. 定义类实现Runnable接口。
    2. 覆盖接口中的run方法。。
    3. 创建Thread类的对象
    4. 将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
    5. 调用Thread类的start方法开启线程。
  • 示例:
public class SubRunnable implements Runnable{
    @Override
    public void run() {
        for(int i=0; i<50; i++) {
            System.out.println("run..."+i);
        }       
    }
}

/**
 * 实现接口方式的线程
 * 创建Thread类对象,构造方法中,传递Runnable接口实现类对象
 * 调用Thread类的方法start
 */
public class RunnableDemo {
    public static void main(String[] args) {
        SubRunnable subRunnable = new SubRunnable();
        Thread t = new Thread(subRunnable);
        t.start();  
        for(int i=0; i<50; i++) {
            System.out.println("main..."+i);
        }
    }
}

1.6.1 实现Runnable接口的原理

  • 思考:为什么需要定一个类去实现Runnable接口呢?继承Thread类和实现Runnable接口有啥区别呢?
    • 实现Runnable接口,避免了继承Thread类的单继承局限性。覆盖Runnable接口中的run方法,将线程任务代码定义到run方法中。
    • 创建Thread类的对象,只有创建Thread类的对象才可以创建线程。线程任务已被封装到Runnable接口的run方法中,而这个run方法所属于Runnable接口的子类对象,所以将这个子类对象作为参数传递给Thread的构造函数,这样,线程对象创建时就可以明确要运行的线程的任务。

1.6.2 实现Runnable的好处

  • 避免局限性、解耦合、资源共享
  • 第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。实现runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。Runnable接口对线程对象和线程任务进行解耦。

1.7 线程的匿名内部类使用

  • 使用线程的内匿名内部类方式,可以方便的实现每个线程执行不同的线程任务操作。
    • 方式1:创建线程对象时,直接重写Thread类中的run方法
    • 方式2:使用匿名内部类的方式实现Runnable接口,重新Runnable接口中的run方法

1.8 线程状态(6种)

  • 线程状态。 线程可以处于以下状态之一:
    • new:尚未启动的线程处于此状态。
    • runnable:在Java虚拟机中执行的线程处于此状态。
    • blocked:被阻塞等待监视器锁定的线程处于此状态。
    • wait:无限期等待另一个线程执行特定操作的线程处于此状态。
    • timed_waiting:正在等待另一个线程执行最多指定等待时间的操作的线程处于此状态。
    • terminated:已退出的线程处于此状态。
  • 线程在给定时间点只能处于一种状态。 这些状态是虚拟机状态,不反映任何操作系统线程状态。

线程状态图:

第二章 线程池

2.1 线程池概念

2.1.1 线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。

线程池示意图:

2.1.2 为什么要使用线程池?

- 在java中,如果每个请求到达就创建一个新线程,开销是相当大的。在实际使用中,创建和销毁线程花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多。除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源。如果在一个JVM里创建太多的线程,可能会使系统由于过度消耗内存或“切换过度”而导致系统资源不足。为了防止资源不足,需要采取一些办法来限制任何给定时刻处理的请求数目,尽可能减少创建和销毁线程的次数,特别是一些资源耗费比较大的线程的创建和销毁,尽量利用已有对象来进行服务。
- 线程池主要用来解决线程生命周期开销问题和资源不足问题。通过对多个任务重复使用线程,线程创建的开销就被分摊到了多个任务上了,而且由于在请求到达时线程已经存在,所以消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使用应用程序响应更快。另外,通过适当的调整线程中的线程数目可以防止出现资源不足的情况。

2.1.3 线程池原理

  • 自己创建线程池
ArrayList<Thread> threads = new ArrayList<Thread>();
threads.add(new Thread());
threads.add(new Thread());
threads.add(new Thread());
threads.add(new Thread());
threads.add(new Thread());
threads.add(new Thread());
threads.add(new Thread());
threads.add(new Thread());
threads.add(new Thread());
threads.add(new Thread());

// 程序一开始的时候,创建多个线程对象,存储到集合中,需要线程,从集合中获取线程出来
Thread t = threads.remove(0);
// 使用线程
t.start();
// 线程用完,回到容器中继续等待使用
threads.add(t);
  • 从JDK5开始,内置线程池技术,不需要自己创建,直接使用即可。

2.2 使用线程池

2.2.1 使用线程池方式--Runnable接口

  • 通常,线程池都是通过线程池工厂创建,再调用线程池中的方法获取线程,再通过线程去执行任务方法。
    ? - Executors:线程池创建工厂类
    ? - public static ExecutorService newFixedThreadPool(int nThreads):返回线程池对象
    ? - ExecutorService:线程池类
    ? - Future<?> submit(Runnable task):获取线程池中的某一个线程对象,并执行
    ? - Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用

  • 使用线程池中线程对象的步骤:
    ? - 创建线程池对象
    ? - 创建Runnable接口子类对象
    ? - 提交Runnable接口子类对象
    ? - 关闭线程池

  • 示例:

public class ThreadPoolRunnable implements Runnable{
    @Override
    public void run() {     
        System.out.println(new Thread().getName());
    }
}


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
 * JDK1.5之后的新特性,实现线程池程序
 *  1、使用工厂类,Executors中的静态方法创建线程对象,指定线程个数
 *  2、static ExecutorsService newFixedThreadPool(int 线程个数)   返回线程池对象
 *  3、返回的是 ExecutorsService接口的实现类(线程池对象)
 *  4、接口实现类对象,调用方法submit(Runnable r) 提交线程,执行任务
 */
public class ThreadPoolDemo {
    public static void main(String[] args) {
        // 调用工厂类的静态方法,创建线程池对象
        // Executors.newFixedThreadPool(2);返回线程池对象,是接口的实现类对象
        ExecutorService es = Executors.newFixedThreadPool(2);
        // 调用接口实现类对象es的方法submit,提交一个线程任务
        es.submit(new ThreadPoolRunnable());
        es.submit(new ThreadPoolRunnable());
        es.submit(new ThreadPoolRunnable());
    }
}
  • Runnable接口的缺陷
    • 线程运行完没有结果
    • 不能抛出异常

2.2.2 使用线程池方式—Callable

  • Callable接口与Runnable接口功能相似,用来指定线程的任务。其中的call()方法,用来返回线程任务执行完毕后的结果,call方法可抛出异常。
    • ExecutorService:线程池类
    • <T> Future<T> submit(Callable<T> task):获取线程池中的某一个线程对象,并执行线程中的call()方法
    • Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用
  • 使用线程池中线程对象的步骤:
    ? - 创建线程池对象
    ? - 创建Callable接口子类对象
    ? - 提交Callable接口子类对象
    ? - 关闭线程池

  • 示例:

import java.util.concurrent.Callable;

public class ThreadPoolCallable implements Callable<String>{
    @Override
    public String call() throws Exception {
        return "abc";
    }
}

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPoolDemo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newFixedThreadPool(2);
        // 提交任务的方法,返回Future接口的实现类
        Future<String> f = es.submit(new ThreadPoolCallable());
        String s = f.get();
        System.out.println(s);
    }
}

2.3 线程池练习:返回多个数相加的结果

import java.util.concurrent.Callable;
/*
 * 多线程的异步计算
 * 
 */
public class GetSumCallable implements Callable<Integer>{
    private int a;
    public GetSumCallable(int a) {
        this.a = a;
    }
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for(int i=0; i<=a; i++) {
            sum += i;
        }
        return sum;
    }   
}

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPoolDemo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newFixedThreadPool(2);
        Future<Integer> f1 = es.submit(new GetSumCallable(100));  // 加法
        Future<Integer> f2 = es.submit(new GetSumCallable(200));  // 减法
        System.out.println("1+2+...+100 = "+f1.get());
        System.out.println("1+2+...+200 = "+f2.get());
        es.shutdown();
    }
}

第三章 总结

创建线程的方式

  • 方式1,继承Thread线程类
    • 步骤
      • 自定义类继承Thread类
      • 在自定义类中重写Thread类的run方法
      • 创建自定义类对象(线程对象)
      • 调用start方法,启动线程,通过JVM,调用线程中的run方法
  • 方式2,实现Runnable接口
    • 步骤
      • 创建线程任务类 实现Runnable接口
      • 在线程任务类中 重写接口中的run方法
      • 创建线程任务类对象
      • 创建线程对象,把线程任务类对象作为Thread类构造方法的参数使用
      • 调用start方法,启动线程,通过JVM,调用线程任务类中的run方法
  • 方式3,实现Callable接口
    • 步骤
      • 工厂类Executors静态方法newFixedThreadPool方法,创建线程对象
      • 线程池对象ExecutorService接口实现类,调用方法submit提交线程任务:submit(Callable c)


















java线程与线程池简单小结

JAVA线程创建方式:1、继承Thread类创建线程类继承Thread类并重写该类的run方法,该un方法代表了线程要完成的任务。2、通过Runnable接口创建线程类实现runnable接口,重写该接口的run()方法,该run()方法的方法体同样是该线程的线程... 查看详情

多线程创建方式

1、继承Thread类创建多线程:继承java.lang.Thread类,重写Thread类的run()方法,在run()方法中实现运行在线程上的代码,调用start()方法开启线程。2、实现Runable接口:实现java.lang.Runnable接口,重写run()方法,在run()方法中实现运行在... 查看详情

java多线程的四种实现方式

1.Java多线程实现的方式有四种:1.继承Thread类,重写run方法2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target3.通过Callable和FutureTask创建线程4.通过线程池创建线程2.Thread实现方式继承Thre... 查看详情

java多线程-java创建线程的4种方式(代码片段)

文章目录1.Java创建线程有哪几种方式?1.1线程创建方法一:继承Thread类创建线程类1.2线程创建方法二:实现Runnable接口创建线程目标类1.5线程创建方法三:使用Callable和FutureTask创建线程1.6线程创建方法四:通过... 查看详情

java线程操作

目录前言创建多线程的方式继承thread抽象类实现Runnable接口匿名内部类线程池线程安全同步代码块同步方法锁机制线程状态前言进程:内存运行的程序。线程:进程中的一个执行单元。创建多线程的方式继承thread抽象类创建publicc... 查看详情

java基础(26):thread线程创建线程池

1.多线程1.1多线程介绍学习多线程之前,我们先要了解几个关于多线程有关的概念。进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功... 查看详情

多线程之线程池技术实现原理,这篇就够了

在Java语言中,有两种比较常见的创建线程的方法,一种是继承Thread类,一种是实现Runnable的接口,Thread类其实也是实现了Runnable接口。并且在前面的博文中我们也介绍了有返回结果的创建线程的方式。这篇博文我们就重点介绍线... 查看详情

java创建多线程(转载)

转载自:Java创建线程的两个方法Java提供了线程类Thread来创建多线程的程序。其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象。每个Thread对象描述了一个单独的线程。要产生一个线... 查看详情

问题整理(多线程)

1、实现线程有哪几种方式继承Thread类实现Runnable接口,重写run()方法实现Callable接口,重写call()方法,返回Future对象结果线程池:ExecutorService中submit(runnable/callable)返回一个Future,Future可用来获得任务的执行结果或者取消任务2、用Ru... 查看详情

26_多线程_第26天(thread线程创建线程池)(代码片段)

今日内容介绍1、多线程2、线程池01进程概念A:进程概念a:进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。02线程的概念A:线程的概... 查看详情

java基础——线程的创建和状态

目录前言创建多线程的方式1继承thread抽象类2实现Runnable接口3实现Callable接口匿名内部类线程池线程安全同步代码块同步方法锁机制线程状态前言进程:内存运行的程序。线程:进程中的一个执行单元。创建多线程的方式本质都... 查看详情

多线程(代码片段)

多线程线程的创建Thread类自定义线程类继承Thread类重写run()方法,编写线程执行体创建线程对象,调用start()方法启动线程publicclassDemo01extendsThreadpublicvoidrun()//重写线程进行内容for(inti=0;i<20;i++)System.out.println("这是线程"+i);//主线... 查看详情

多线程(thread线程创建线程池)

 第1章 多线程1.1 多线程介绍学习多线程之前,我们先要了解几个关于多线程有关的概念。进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并... 查看详情

多线程

进程和线程的区别是什么?进程是执行着的应用程序,而线程是进程内部的一个执行序列.一个进程可以有多个线程.线程又叫做轻量级进程.创建线程有几种方式?有三种方式:继承Thread类实现Runnable接口应用程序可以使用Executor框架来... 查看详情

java多线程实现(四种方法)

...un方法3.实现Callable接口,重写call方法(有返回值)4.使用线程池(有返回值) 1.继承Thread类,重写run方法  每次创建一个新的线程,都要新建一个Thread子类的对象  启动线程,newThread子类().start()p 查看详情

java多线程-五种线程创建方式

简单使用示例Java提供了三种创建线程的方法:通过实现Runnable接口;通过继承Thread类本身;通过Callable和Future创建线程。还有定时器线程池下面第一个类给出了四种创建方式,第二个类是定时器示例。①publicclassThreadStartTest{publics... 查看详情

java进程,多线程详解(代码片段)

...际上,CPU每一段时间只能运行一个应用程序。 进程与线程一个操作系统可以有多个进程,进程可以简单的看做是正在执行中的应用程序。进程是多个线程的集合,一个进程中至少有一个线程,我们知道,代码是从上往下执行... 查看详情

java多线程与线程池技术

一、序言Java多线程编程线程池被广泛使用,甚至成为了标配。线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批线程,当... 查看详情