多线程——背景了解

文章目录

  • 前言
  • 叙述
    • 宝图
      • 线程与进程
      • 同步与异步
      • 五种状态
      • 守护线程与非守护线程
      • 创建线程的四种方式
      • 比较
  • 总结

前言

  小咸儿要开始向多线程的领域进军了,第一件事当然是先来了解一下它的背景,这样才能够宏观把控,立于不败之地。首先先来学习几个概念:


叙述

宝图

多线程——背景了解_第1张图片

线程与进程

  进程:就是独立的一个应用程序,在进程中,会有N多个线程。例如一列火车

  线程:一条执行路径。例如每一节火车车厢

  多线程:所有线程的集合。例如多节火车车厢

  多线程的目的: 提高程序效率,而不能提高下载速度。

同步与异步

  同步:代码自上至下顺序执行
多线程——背景了解_第2张图片

  异步:新的执行路径,不会影响其他的线程
多线程——背景了解_第3张图片

五种状态

  这里的五种状态,指的是线程的五种状态:新建、就绪、运行、阻塞、死亡

  那么这五种状态是如何转化的呢?
多线程——背景了解_第4张图片

守护线程与非守护线程

  守护线程:也被成为后台线程,即和main相关的线程,其中典型代表JVM的垃圾回收线程

  非守护线程:用户线程属于非守护线程,即用户创建的线程,如果主线程停止掉,不会影响用户。如果将非守护线程设置为守护线程,也十分的简单,调用Thread对象的setDaemon(true)方法即可。

new Thread.setDaemon(true)

创建线程的四种方式

  继承Thread类,并重写run()方法

package com.practice.demo.thread;

/**
 * 线程的第一个实例,继承Thread类
 * @author Phyllis
 * @date 2019年6月30日15:08:26
 */
public class FirstThread extends Thread{
    private int i;

    /**
     * 重写run()方法,run()方法的方法体就是线程执行体
      */
    @Override
   public void run(){
       for (; i<100 ;i++){
           // 当线程类继承Thread类时,直接使用this即可
           System.out.println(getName()+"     "+i);
       }
   }
   public static void main(String[] args){
        for (int i=0; i<100; i++){
            // 调用Thread的currentThread()方法获取当前线程
            System.out.println(Thread.currentThread().getName()+"   "+i);
            if (i == 20){
                // 创建并启动第一个线程
                new FirstThread().start();
                // 创建并启动第二个线程
                new FirstThread().start();
            }
        }
   }
}


  实现Runnable接口,并重写run()方法

package com.practice.demo.thread;

/**
 * 线程的第二个实例,实现Runnable接口
 * @author Phyllis
 * @date 2019年7月2日17:26:05
 */
public class SecondThread implements Runnable{
    private int i;

    /**
     * run()方法同样是线程执行体
     */
    @Override
    public void run() {
        for (; i < 100; i++){
            // 当线程类实现Runnable接口时
            // 如果想获取当前线程,只能用Thread.currentThread()方法
            System.out.println(Thread.currentThread().getName()+"   "+i);
        }
    }
    public static void main(String[] args){
        for (int i = 0; i<100; i++){
            System.out.println(Thread.currentThread().getName()+"   "+i);
            if (i == 20){
                SecondThread st = new SecondThread();
                // 通过new Thead(target,name)方法创建新线程
                new Thread(st, "新线程1").start();
                new Thread(st,"新线程2").start();
            }
        }
    }
}

  匿名内部类

public class Thread003 {

	public static void main(String[] args) {
		System.out.println("main... 主线程开始...");

		Thread t1 = new Thread(new Runnable() {

			public void run() {
				for (int i = 0; i < 10; i++) {
					System.out.println(" 子 i:" + i);
				}
			}
		});
		t1.start();
		for (int i = 0; i < 10; i++) {
			System.out.println("main..i:" + i);
		}
		System.out.println("main... 主线程结束...");
	}
}

  使用Callable和Future创建线程

package com.practice.demo.thread;

/**
 * 线程的第三个实例,使用Callable和Future创建线程
 * @author Phyllis
 * @date 2019年7月2日17:26:05
 */
public class ThirdThread implements Runnable{
    
    public static void main(String[] args){
    	// 创建Callable对象
    	ThirdThread rt = new ThirdThred();
    	// 先试用Lambda表达式创建Callable对象
    	// 使用FutureTask来包装Callable对象
    	FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)()->{
    		int i = 0;
    		for(; i < 100; i++){
				System.out.println(Thread.currentThread().getName() + " 的循环变量i的值:" + i);
			}
			return i;
    	});
    	for (int i = 0; i < 100; i++){
			System.out.println(Thread.currentThread().getName() + " 的循环变量i的值:" + i);
			if(i == 20){
				// 实质上还是以Callable对象来创建和启动线程的
				new Thread(task, "有返回值的线程").start();
			}
		}
		try{
			// 获取线程返回值
			System.out.println("子线程的返回值:" + task.get());
		}
		catch (Exception ex){
			ex.printStackTrace();
		}
    }
}

比较

采用实现Runnable、Callable接口的方式创建多线程的优缺点:

优点:

  • 线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。
  • 在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开、形成清晰地模型,较好的体现了面向对象的思想。

缺点:

  • 编程稍稍复杂,如果需要访问当前线程,则必须使用Thread.currentThread()方法。

采用继承Thread类的方式创建多线程的优缺点:

优点:

  • 编写简单,如果需要访问当前线程,则无须使用Thread.currentThread()方法,直接使用this即可获得当前线程。

缺点:

  • 因为继承了Thread类,类只能进行单继承,所以无法继承其他的类。

总结

  多线程是十分实用并且常用的内容,接下来小咸儿还会继续深入学习多线程,更多的内容等待更新。

感谢您的阅读~~

你可能感兴趣的:(¤JAVA¤,多线程)