首页 > 其他分享 >多线程

多线程

时间:2024-10-19 16:33:12浏览次数:1  
标签:Thread void class 线程 new 多线程 public

第七章——多线程

1、多线程概述

1、多线程概述
进程:
正在运行的程序,是系统进行资源分配和调用的独立单位。
每一个进程都有它自己的内存空间和系统资源。
线程:
是进程中的单个顺序控制流,是一条执行路径
一个进程如果只有一条执行路径,则称为单线程程序。
一个进程如果有多条执行路径,则称为多线程程序。
举例
扫雷游戏,百度网盘下载等

    
2、Java程序运行原理:
java 命令会启动 java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程。该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 main 方法。所以 main方法运行在主线程中。在此之前的所有程序都是单线程的。
思考:
jvm虚拟机的启动是单线程的还是多线程的?主线程 垃圾回收线程
    
答:虚拟机(VM)的启动通常是由单个线程进行的,即主线程(main thread)。在 Java 虚拟机中,当 Java 程序启动时,JVM 会启动一个主线程来执行 main 方法,这是程序的入口点。
以下是关于主线程和垃圾回收线程的几个要点:
主线程:
主线程负责启动 JVM 和执行 main 方法。
main 方法是程序的入口点,它通常由用户或命令行工具触发。
在 main 方法执行期间,程序的其他线程(如果有)会等待主线程的执行。
垃圾回收线程:

垃圾回收(GC)是 JVM 自动管理内存的过程,用于回收不再使用的对象占用的内存。
垃圾回收线程是 JVM 内部的一个守护线程(daemon thread),它在后台运行,不需要主线程的干预。
守护线程会等待除守护线程之外的所有线程都结束时才会结束,因此它会在主线程执行完毕后继续运行,直到 JVM 关闭。    
    

2、多线程的实现方案1 继承Thread类:

继承Thread类:
/*
    休眠线程
    public static void sleep(long millis)

 */
class MyThread2 extends Thread{
    @Override
    public void run() {
        System.out.println("我是李刚,现在开始睡觉了...");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("我醒了,现在开始学习!!");
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        MyThread2 myThread2 = new MyThread2();
        myThread2.start();
    }
}

============================================================

/*
    休眠线程
    public static void sleep(long millis)

 */
class MyThread2 extends Thread{
    @Override
    public void run() {
        System.out.println("我是李刚,现在开始睡觉了...");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("我醒了,现在开始学习!!");
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        MyThread2 myThread2 = new MyThread2();
        myThread2.start();
    }
}
============================================================/*
    加入线程:
        public final void join()

 */
class MyThread3 extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 200; i++) {
            System.out.println(getName() + "-" + i);
        }
    }
}

public class                                                                                                                                                            ThreadDemo3 {
    public static void main(String[] args) throws InterruptedException {
        MyThread3 t1 = new MyThread3();
        MyThread3 t2 = new MyThread3();
        MyThread3 t3 = new MyThread3();


        t1.start();
        t1.join();

        t2.start();
        t3.start();
    }
}

/*
    礼让:
        public static void yield()
 */

class MyThread4 extends Thread{
    @Override
    public void run() {
        for(int i=1;i<=200;i++){
            System.out.println(getName()+"- "+i);
            Thread.yield();
        }
    }
}

public class ThreadDemo4 {
    public static void main(String[] args) {
        MyThread4 t1 = new MyThread4();
        MyThread4 t2 = new MyThread4();

        t1.start();
        t2.start();
    }
}
============================================================
/*
    后台线程:
        public final void setDaemon(boolean on)


    用户线程:优先级高于守护线程
    守护线程【后台线程】:当一个程序没有了用户线程,守护线程也就没有了
 */

class MyThread5 extends Thread{
    @Override
    public void run() {
        for(int i=1;i<=200;i++){
            System.out.println(getName()+"- "+i);
        }
    }
}

public class ThreadDemo5 {
    public static void main(String[] args) {
        MyThread5 t1 = new MyThread5();
        MyThread5 t2 = new MyThread5();
        MyThread5 t3 = new MyThread5();

        t1.setName("刘备");
        t2.setName("关羽");
        t3.setName("张飞");

        //将t2和t3线程设置为守护线程
        t2.setDaemon(true);
        t3.setDaemon(true);

        t1.start();
        t2.start();
        t3.start();
    }
}    
============================================================  /*
    中断线程:
        public final void stop()
        public void interrupt()

    java所有的线程要想变成运行状态,必须经过抢cpu执行权

 */
class MyThread6 extends Thread{
    @Override
    public void run() {
        System.out.println("胡海祥准备睡觉了....睡足10秒钟");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("睡醒了,继续敲代码!!!");
    }
}

public class ThreadDemo6 {
    public static void main(String[] args) {
        MyThread6 t1 = new MyThread6();
        t1.start();

        try {
            Thread.sleep(5000);
//            t1.stop();
            t1.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
  

3、多线程的实现方案2 实现Runnable接口

实现接口方式的好处
可以避免由于Java单继承带来的局限性。
适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,较好的体现了面向对象的设计思想。


/*
    创建线程的第二种方式:实现Runnable接口,借助Thread类创建线程对象

    若将来每一个线程执行的逻辑是一样的话,推荐采用第二种实现Runnable接口方式实现多线程
    若将来每一个线程执行逻辑不一样的话,推荐采用第一种继承Thread类方式实现多线程
 */

class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 200; i++) {
            //可以先通过获取当前执行的线程对象,调用内部getName()方法
            System.out.println(Thread.currentThread().getName()+"-"+i);
        }
    }
}

public class RunnableDemo1 {
    public static void main(String[] args) {
        //创建Runnable对象
        MyRunnable r1 = new MyRunnable();
        //创建线程对象
//        Thread t1 = new Thread(r1);
//        Thread t2 = new Thread(r1);
//        Thread t3 = new Thread(r1);
        //创建线程对象同时起名字
        Thread t1 = new Thread(r1, "李刚");
        Thread t2 = new Thread(r1, "祝帅");
        Thread t3 = new Thread(r1, "吴问强");

        //获取线程优先权 默认线程优先级是 5
//        System.out.println("t1: "+t1.getPriority());
//        System.out.println("t2: "+t2.getPriority());
//        System.out.println("t3: "+t3.getPriority());
        t1.setPriority(1); // 1-10
        t1.setPriority(10);
        t1.setPriority(1);

        t1.start();
        t2.start();
        t3.start();
    }
}

4、解决线程安全问题的基本思想

首先想为什么出现问题?(也是我们判断是否有问题的标准)
是否是多线程环境
是否有共享数据
是否有多条语句操作共享数据
如何解决多线程安全问题呢?
基本思想:让程序没有安全问题的环境。
怎么实现呢?
把多个语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可。

    
1、解决线程安全问题实现1
同步代码块
格式:
		synchronized(对象){需要同步的代码;}
同步可以解决安全问题的根本原因就在那个对象上。该对象如同锁的功能。    

同步的前提
多个线程
多个线程使用的是同一个锁对象
同步的好处
同步的出现解决了多线程的安全问题。
同步的弊端
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

    
2、解决线程安全问题实现2
同步方法
就是把同步关键字加到方法上
同步方法的锁对象是什么呢?

如果是静态方法,同步方法的锁对象又是什么呢?
那么,我们到底使用谁?
如果锁对象是this,就可以考虑使用同步方法。
否则能使用同步代码块的尽量使用同步代码块    
    
3、某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。
   
/*
    使用继承Thread类来实现售票案例
 */
class Window extends Thread{
    static int tickets = 100;

    @Override
    public void run() {
//        int tickets = 100;
        while (true){
            if(tickets>0){
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("当前 " + getName()+" 正在出售第 "+(tickets--)+" 张票");
            }
        }
    }
}

public class SellTicketsDemo1 {
    public static void main(String[] args) {
        Window w1 = new Window();
        Window w2 = new Window();
        Window w3 = new Window();

        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");

        w1.start();
        w2.start();
        w3.start();
    }
}

============================================================

/*
    使用实现Runnable接口的方式实现售票

    问题1:我们加入了循环和延迟模拟现实生活售票的场景后发现
        1. 出现售卖重复的票号 【计算机中cpu的计算是具备原子性的】
        2. 出现非法的票号  【随机性导致的,cpu小小的时间片,足以执行很多次】

    上述的问题1实际上是属于线程安全的问题。
    如何判断一个程序是否存在线程安全的问题呢?
    三要素,缺一不可:
        1、是否存在多线程环境? 是
        2、是否存在共享数据/共享变量?是tickets
        3、是否存在多条语句操作着共享数据/共享变量? 是

    怎么解决?
        方案1:同步代码块
            synchronized(对象){需要同步的代码;}  这里对象要保证多个线程对象唯一的
            同步方法:锁对象是this
            同步静态方法:锁对象是当前类的class文件对象   类.class
        方案2:lock锁



 */
class Window2 implements Runnable{
    int tickets = 200;
    Object obj = new Object();

    @Override
    public void run() {
        while (true){
            synchronized (obj){
                if(tickets>0){ // 1
                    try {
                        // t1
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println("当前 " + Thread.currentThread().getName()+" 正在出售第 "+(tickets--)+" 张票");
                }
            }

        }
    }
}


public class SellTicketsDemo2 {
    public static void main(String[] args) {
        Window2 window2 = new Window2();

        Thread t1 = new Thread(window2, "窗口1");
        Thread t2 = new Thread(window2, "窗口2");
        Thread t3 = new Thread(window2, "窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

============================================================

/*
    同步方法的锁对象
 */
class Window3 implements Runnable {
    static int tickets = 200;
    int i = 0;

    @Override
    public void run() {
        while (true) {
            if (i % 2 == 0) {
                synchronized (Window3.class) {
                    if (tickets > 0) { // 1
                        try {
                            // t1
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        System.out.println("当前 " + Thread.currentThread().getName() + " 正在出售第 " + (tickets--) + " 张票");
                    }
                }
            } else {
                sell();
            }

            i++;
        }
    }

    public synchronized static void sell() {
        if (tickets > 0) { // 1
            try {
                // t1
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("当前 " + Thread.currentThread().getName() + " 正在出售第 " + (tickets--) + " 张票");
        }
    }


//    public synchronized void sell() {
//        if (tickets > 0) { // 1
//            try {
//                // t1
//                Thread.sleep(20);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//
//            System.out.println("当前 " + Thread.currentThread().getName() + " 正在出售第 " + (tickets--) + " 张票");
//        }
//    }
}


public class SellTicketsDemo3 {
    public static void main(String[] args) {
        Window3 window3 = new Window3();

        Thread t1 = new Thread(window3, "窗口1");
        Thread t2 = new Thread(window3, "窗口2");
        Thread t3 = new Thread(window3, "窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

============================================================

/*
    使用lock锁来解决线程安全的问题
 */
class Window4 implements Runnable {
    int tickets = 200;
    Object obj = new Object();
    ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
            // 加锁
            lock.lock();
            if (tickets > 0) { // 1
                try {
                    // t1
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("当前 " + Thread.currentThread().getName() + " 正在出售第 " + (tickets--) + " 张票");
            }
            //释放锁
            lock.unlock();
        }
    }
}


public class SellTicketsDemo4 {
    public static void main(String[] args) {
        Window4 window4 = new Window4();

        Thread t1 = new Thread(window4, "窗口1");
        Thread t2 = new Thread(window4, "窗口2");
        Thread t3 = new Thread(window4, "窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}
============================================================

/*
    死锁:线程之间存在相互等待的现象

    案例:中国人和外国人
        前提:中国人吃饭必须要两支筷子,外国人吃饭必须一把刀和一把叉
        现在:
            中国人:一支筷子和一把刀
            外国人:一支筷子和一把叉
 */

class Person extends Thread{
    boolean flag;

    public Person(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if(flag){
            synchronized (Locks.LOCK1){
                System.out.println("if lock1");
                // p1
                synchronized (Locks.LOCK2){
                    System.out.println("if lock2");
                }
            }
        }else {
            synchronized (Locks.LOCK2){
                System.out.println("else lock2");
                // p2
                synchronized (Locks.LOCK1){
                    System.out.println("else lock1");
                }
            }
        }
    }
}

public class DieLock {
    public static void main(String[] args) {
        Person p1 = new Person(true);
        Person p2 = new Person(false);

        p1.start();
        p2.start();
    }
}



5、线程组 线程池

/*
    线程组:将属于同一类的线程划分到同一组中,可以直接对线程组进行设置。

    ThreadGroup
        构造方法:
            ThreadGroup(String name) 构造一个新的线程组。

 */
class MyThread1 extends Thread{
    public MyThread1() {
    }

    public MyThread1(ThreadGroup group, String name) {
        super(group, name);
    }

    @Override
    public void run() {
        System.out.println("这是帅哥线程");
    }
}

public class ThreadGroupDemo1 {
    public static void main(String[] args) {
        //创建一个线程组,组名叫做帅哥组
        ThreadGroup tg1 = new ThreadGroup("帅哥组");
        ThreadGroup tg2 = new ThreadGroup("美女组");


        //创建两个线程对象,分配到线程组中
//        MyThread1 t1 = new MyThread1();
//        t1.setName("李刚");
        //Thread(ThreadGroup group, String name)
        //分配一个新的 Thread对象。
        MyThread1 t1 = new MyThread1(tg1, "李刚");
        MyThread1 t2 = new MyThread1(tg1, "钱志强");
        MyThread1 t3 = new MyThread1(tg2, "李世博");
        MyThread1 t4 = new MyThread1(tg2, "杨珊珊");

        System.out.println(t1.getName()+"属于 "+t1.getThreadGroup().getName());
        System.out.println(t2.getName()+"属于 "+t2.getThreadGroup().getName());
        System.out.println(t3.getName()+"属于 "+t3.getThreadGroup().getName());
        System.out.println(t4.getName()+"属于 "+t4.getThreadGroup().getName());


//        t1.setDaemon(true);
//        t2.setDaemon(true);
        tg1.setDaemon(true);

    }
}
============================================================
    
/*
    线程池:ThreadPool

    Executors:
        static ExecutorService newCachedThreadPool() 创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。
        static ExecutorService newFixedThreadPool(int nThreads) 创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
        static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。
 */
class MyRunnable implements Runnable {

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }
}

class MyCallable implements Callable{

    @Override
    public Object call() throws Exception {
        for (int i = 1; i <= 100; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
        return null;
    }
}

public class ThreadPoolDemo1 {
    public static void main(String[] args) {
        //创建一个固定大小的线程池
        ExecutorService pool = Executors.newFixedThreadPool(2);

        //Future<?> submit(Runnable task);
//        pool.submit(new MyRunnable());
//        pool.submit(new MyRunnable());
//        pool.submit(new MyRunnable());


        // <T> Future<T> submit(Callable<T> task);
//        pool.submit(new MyCallable());
//        pool.submit(new MyCallable());
        pool.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                for (int i = 1; i <= 100; i++) {
                    System.out.println(Thread.currentThread().getName() + " - " + i);
                }
                return null;
            }
        });

//        pool.submit(new Callable<Object>() {
//            @Override
//            public Object call() throws Exception {
//                //....
//                return null;
//            }
//        });

        //关闭线程池
        pool.shutdown();
    }
}

6、定时器

定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后台线程的方式执行。在Java中,可以通过Timer和TimerTask类来实现定义调度的功能
Timer
public Timer()
public void schedule(TimerTask task, long delay)
public void schedule(TimerTask task,long delay,long period)
TimerTask
public abstract void run()
public boolean cancel()
开发中
Quartz是一个完全由java编写的开源调度框架。
    
/*
    定时器:Timer
    定时任务:TimerTask
 */
public class TimerDemo1 {
    public static void main(String[] args) {
        //创建一个定时器
        Timer timer = new Timer();

        //public void schedule(TimerTask task, long delay) 延迟多少毫秒后执行定义任务
        timer.schedule(new MyTask(timer), 5000);

        //public void schedule(TimerTask task,long delay,long period) 延迟delay毫秒后执行定义任务,后续每间隔period毫米执行一次
        timer.schedule(new MyTask(timer), 5000,2000);
    }
}

class MyTask extends TimerTask{
    Timer timer;

    public MyTask(Timer timer) {
        this.timer = timer;
    }

    @Override
    public void run() {
        System.out.println("砰!爆炸了.....");
//        timer.cancel();
    }
}
   

7、单例设计模式

/*
    单例模式:在整个java程序运行期间,内存中某一个对象有且仅只能有一个。笔试
        1. 饿汉式 工作开发中
        2. 懒汉式 面试的时候说,可能会涉及线程安全的问题。

 */
public class DanLiDemo1 {
    public static void main(String[] args) {
//        Student1 s1 = Student1.getStudent1();
//        Student1 s2 = Student1.getStudent1();
//        System.out.println(s1==s2);

        Student2 s1 = Student2.getStudent2();
        Student2 s2 = Student2.getStudent2();
        System.out.println(s1==s2);
    }
}


/*
    饿汉式
 */
public class Student1 {
    private static Student1 student1 = new Student1();

    private Student1(){}

    public static Student1 getStudent1(){
        return student1;
    }
}


/*
    懒汉式
 */
// t1, t2, t3
public class Student2 {
    private static Student2 student2;

    private Student2(){}

    public synchronized static Student2 getStudent2(){
        if(student2==null){
            // t1 , t2, t3
            student2 = new Student2();
        }

        return student2;
    }
}

8、设计模式

/*
    设计模式:
        创建型模式
            简单工厂模式
            工厂方法模式
            单例模式
        行为型模式
        结构型模式
 */
public class FactoryDemo1 {
    public static void main(String[] args) {
        //养一只狗
        Animal d1 = AnimalFactory.createAnimal("dog");
        //养一只猫
        Animal c1 = AnimalFactory.createAnimal("cat");

    }
}
============================================================
public abstract class Animal {
    public abstract void eat();

    public abstract void sleep();
}
============================================================
public class AnimalFactory {
    private AnimalFactory() {
    }

    public static Animal createAnimal(String name){
        if("dog".equals(name)){
            return new Dog();
        }else if("cat".equals(name)){
            return new Cat();
        }else {
            System.out.println("没有该动物");
            return null;
        }
    }
}
============================================================public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫蜷着睡");
    }
}
============================================================public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }

    @Override
    public void sleep() {
        System.out.println("狗侧着睡");
    }
}



标签:Thread,void,class,线程,new,多线程,public
From: https://www.cnblogs.com/snzjz/p/18475758

相关文章

  • java_day18_多线程、线程安全问题、死锁、等待唤醒机制
    一、线程1、多线程进程:是系统进行资源分配和调用的独立单位,每一个进程都有它自己的内存空间和系统资源。举例:IDEA,阿里云盘,wegame,steam线程:是进程中的单个顺序控制流,是一条执行路径一个进程如果只有一条执行路径,则称为单线程程序。一个进程如果有多条执行......
  • 多线程
    进程:是系统进行资源分配和调用的独立单位,每一个进程都有它自己的内存空间和系统资源。举例:IDEA,阿里云盘,wegame,steam线程:是进程中的单个顺序控制流,是一条执行路径一个进程如果只有一条执行路径,则称为单线程程序。一个进程如果有多条执行......
  • 【Java】多线程 Start() 与 run() (简洁实操)
    Java系列文章目录补充内容Windows通过SSH连接Linux第一章Linux基本命令的学习与Linux历史文章目录Java系列文章目录一、前言二、学习内容:三、问题描述start()方法run()方法四、解决方案:4.1重复调用.run()4.2重复调用start()4.3正常调用start()不会报出......
  • java多线程
    学习java多线程packagecom.haole.testdemo1;classRunnableDemo3implementsRunnable{privateStringname;privateThreadx;RunnableDemo3(Stringa){name=a;}@Overridepublicvoidrun(){for(inti=0;i<4;......
  • 多线程(五):死锁&内存可见性问题
    目录1.synchronized---监视器锁monitorlock2.死锁2.1死锁---情况12.1.1可重入2.1.2 如何实现一个可重入锁[面试题]2.2死锁---情况22.2.1BLOCKED2.2.2手写死锁代码[经典面试题]2.3 死锁---情况33.避免死锁的出现3.1构成死锁的四个必要条件★......
  • 【Linux线程】Linux多线程编程:深入理解线程互斥与同步机制
    ......
  • Java多线程编程:深入理解与实践
    java笔记,点击下载在现代软件开发中,多线程编程已成为提高程序性能和响应能力的关键技术之一。Java作为一门高级编程语言,提供了丰富的多线程支持,使得开发者能够轻松地编写并发程序。本文将深入探讨Java多线程的基本概念、实现方式以及最佳实践。多线程的基本概念多线程是指......
  • 一个月学会Java 第20天 多线程
    Day20多线程线程,很重要的概念,因为我们的CPU假如是intel或者amd的都是说一核二线程,假如你的电脑是8核的cpu那基本上就是16线程,如果你的mac的M芯片自然是几核就是几线程。想要查看自己的电脑是几个线程的我们有几种方法,一种直接使用Java运行一串代码,其次我们可以看任务管......
  • 【Linux】<互斥量>解决<抢票问题>——【多线程竞争问题】
    前言大家好吖,欢迎来到YY滴Linux系列,热烈欢迎!本章主要内容面向接触过C++的老铁主要内容含:欢迎订阅YY滴C++专栏!更多干货持续更新!以下是传送门!YY的《C++》专栏YY的《C++11》专栏YY的《Linux》专栏YY的《数据结构》专栏YY的《C语言基础》专栏YY的《初学者易错点》......
  • 【Linux】解锁线程基本概念和线程控制,步入多线程学习的大门
    目录1、线程初识1.1线程的概念1.2.关于线程和进程的进一步理解1.3.线程的设计理念1.4.进程vs线程(图解)1.5地址空间的第四谈2.线程的控制:2.1.关于线程控制的前置知识2.2创建线程的系统调用:这个几号手册具体代表的什么含义?2.3.线程终止我们怎么没有像进程一样获取线程......