第十七章 多线程的并发进程

一.进程和线程的区别与联系

  1. 区别
  • 定义:进程是程序执行的实例,它拥有独立的内存空间和资源。线程是进程的子任务,共享相同的内存空间和资源。
  • 管理:进程由操作系统管理,每个进程拥有独立的地址空间。而线程在进程内部创建和调度,共享进程的地址空间。
  • 资源消耗:由于每个进程拥有独立的内存空间和资源,进程间切换开销较大。线程共享相同的内存空间,线程间切换开销较小。
  • 通信和同步:进程间通信需要使用特定的机制,如管道、消息队列、共享内存等。线程间通信更为简单,可以通过共享变量直接进行。
  1. 联系
  • 关联性:线程是进程的一部分,一个进程可以包含多个线程。线程共享进程的资源,它们之间相互协作完成任务。
  • 并发执行:进程和线程都可以实现程序的并发执行,提高系统的效率和资源利用率。
  • 共享资源:进程和线程都可以访问和操作共享的资源,需要在多线程编程中注意同步和互斥的问题。

二.实现多线程的方式

  1. 常见的两种
  • 继承Thread类,重写run方法
//MyThread.java
public class MyThread extends Thread{ // MyThread就是一个线程类。
    @Override
    public void run() {
        for(int i = 0; i < 1000; i++){
            System.out.println("MyThread在执行--->" + i);
        }
    }
}

//ThreadTest01.java
public class ThreadTest01 {
    // 通过继承Thread类来创建线程
    public static void main(String[] args) {
        // 怎么创建线程对象?
        MyThread t = new MyThread(); // t就是一个线程对象。
        // 怎么启动一个线程?
        // 以下代码表示在主线程中,使用线程的start方法来启动分支线程。
        // 分支线程的启动,表示在JVM当中分配一个新的栈内存。
        t.start(); // 这个方法调用之后,会开启新的栈内存。开启一个新的分支线程。(只要开启之后两个线程就互不干扰了。各自执行各自的。)
        //t.run(); // 这不会启动新的线程,只是普通方法调用。

        for (int i = 0; i < 1000; i++) {
            System.out.println("main线程--->" + i);
        }
    }
}
  • 实现Runnable接口,实现run方法
//MyRunnable.java
public class MyRunnable implements Runnable{ // MyRunnable不是一个线程,只是一个实现了Runnable接口的类。
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("MyRunnable--->" + i);
        }
    }
}

//ThreadTest01.java
public class ThreadTest01 {
    public static void main(String[] args) {
        // 创建线程对象
        Thread t = new Thread(new MyRunnable());
        // 启动线程
        t.start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("main线程---->" + i);
        }
        new Thread(()->{
            System.out.println("x线程执行了。");
        }).start();
    }
}

三.获取当前线程对象的引用

public class ThreadTest01 {
    //获得当前线程对象的引用
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.setName("t线程");
        t.start();

        // 这个代码出现在主线程中,那么获取的当前线程对象一定是主线程。
        Thread x = Thread.currentThread();
        System.out.println(x.getName());
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            // 这里怎么获取当前线程对象?
            //System.out.println(Thread.currentThread());
            Thread t = Thread.currentThread();
            //System.out.println(t == this);
            // 获取当前线程的名字
            System.out.println("当前线程名:" + t.getName());
        }
    }
}

四.线程的生命周期

线程生命周期

五.线程的休眠

public class ThreadTest {
    // 线程睡眠,会放弃占有的CPU
    public static void main(String[] args) {

        Thread t = new MyThread();
        t.setName("t");
        t.start();

        // Thread.sleep(毫秒)
        // 静态方法
        // 单位是毫秒
        // 出现在哪里就阻塞哪里。表示让当前线程进入休眠状态。
        // 如果写到这里就是让主线程进入休眠
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + "==>" + i);
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class MyThread extends Thread {
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + "==>" + i);
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

六.后台线程的特点

public class ThreadTest01 {
    /*
    守护线程/后台线程:
        1.线程分类:
            第一类:用户线程/前台线程
            第二类:守护线程/后台线程。
        2.所有的守护线程一般情况下是不会结束的,守护线程在什么时候会结束呢?
            当所有的用户线程结束之后,守护线程自动结束。
        3. java程序中有一个非常经典的守护线程:垃圾回收线程。
     */
    public static void main(String[] args) {
        // t线程是守护线程
        // main线程是用户线程
        Thread t = new MyThread();
        t.setName("t");

        // 将t线程设置为后台线程。
        t.setDaemon(true);

        t.start();

        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "--->" + i);
        }
    }
}

class MyThread extends Thread {
    public void run(){
        int i = 0;
        while(true){
            i++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "==>" + i);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是柒浔啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值