Java中线程的学习

news2025/1/17 19:38:04

目录​​​​​​​

程序,进程,线程  

创建线程

继承Thread类

实现Runnable接口

Thread类中方法

线程优先级

线程状态

多线程的概念

线程同步

在Java代码中实现同步

以下代码使用继承Thread方式实现

以下代码使用实现Runnable方式实现

Lock(锁)

线程通信

案例一:两个线程交替打印1-100之间的数字

案例二:生产者/消费者问题

新增创建线程方式


程序,进程,线程  

     程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码.

     进程((process)正在内存中运行的应用程序,如运行中的QQ,运行中的音乐播放器。进程是操

作系统进行资源分配的最小单位.

     线程(thread)进程可进一步细化为线程,是一个进程内部的最小执行单元,是操作系统进行调度

的最小单元,隶属于进程.

进程和线程的关系:

     一个进程可以包含多个线程

     一个线程只能属于一个进程,线程不能脱离进程而独立运行

    每一个进程最少包含一个线程(主线程)

     主线程可以创建并运行其他线程

      一个进程中所有的线程共享该进程的内存资源

创建线程

  创建线程的方式有俩种:

           1.继承Thread类

           2.实现Runnable接口

继承Thread类

        Thread类中的run方法本身并不执行任何操作,如果我们重写了run方法,当线程启动时,它将执行 run方法。

           在Java中要实现线程,可以继承Thread类,重写其中的run方法。

/*
Java中创建线程方式1
    创建一个类继承java.lang.Thread

    重写run()方法
 */
public class MyThread extends Thread{
    /*
    线程中要执行的任务都要写在run()方法中,或者在run()中调用
     */
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("MyThread"+i);
        }
    }
}

以下是测试代码:

public class TestThread {
    public static void main(String[] args) {
        MyThread myThread=new MyThread();
        //myThread.run();   这不是启动线程,知识方法调用,还是单线程模式
        myThread.start();//启动线程


        for (int i = 0; i < 1000; i++) {
            System.out.println("main"+i);
        }
        /*
        根据代码运行情况,其中main+i和MyThread+i交错执行,说明程序并非单线程模式
         */
    }
}

实现Runnable接口

          java.lang.Runnable接口中仅仅只有一个抽象方法: public void run()      

          实现Runnable接口的方式来实现线程,只需要实现其中的run方法即可
/*
java中创建线程的方式2
  创建一个类继承Runnable接口

   需要完成的线程任务加入到run方法中
   优点:
       1.java是但继承类,继承了一个类就不能继承另一个类,这样做可以避免单继承的局限
       2.适合多线程来处理同一份资源
 */
public class TaskThread implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("任务线程"+i);
        }
    }
}

以下是测试代码:

public class TestTask {
    public static void main(String[] args) {
        //创建任务
        TaskThread taskThread=new TaskThread();
        //创建线程
        Thread thread=new Thread(taskThread);
        thread.start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("main"+i);
        }
    }
}

实现Runnable接口的好处:

       1.避免了单继承的局限性

       2.多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。

Thread类中方法

public class MyThread extends Thread{
            /*
            Thread类中的方法:
                run()  用来定义线程中要执行的任务的代码
                start()   启动线程
                currentThread()   获取到当前线程
                getId()   获取线程Id
                setName()  设置线程名字
                getName()  获取线程名字
                setPriority(10)     设置线程优先级  为1-10(1是最低,10是最高) 默认为5 作用是为操作系统调度算法提供的
                getPriority()   获取线程优先级
                getState()   获取线程当前状态
                sleep()  让线程阻塞休眠指定的时间  单位是毫秒
                join()  等待调用了join()方法的线程执行完毕,才能执行其他线程
                yield()  主动礼让  退出CPU
         */

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(Thread.currentThread());
            System.out.println(Thread.currentThread().getId());
            System.out.println(Thread.currentThread().getName());
            System.out.println(Thread.currentThread().getPriority());
            System.out.println(Thread.currentThread().getState());
            System.out.println(Thread.currentThread().getId());

            try {
                Thread.sleep(2000);//让线程阻塞休眠指定的时间  单位是毫秒
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

以下是测试代码:

public class TestMy {
    public static void main(String[] args) {
        MyThread myThread=new MyThread();
        myThread.start();

        for (int i = 0; i < 1000; i++) {
            System.out.println(Thread.currentThread());
        }
    }

}

线程优先级

      优先级较高的线程有更多获得CPU的机会,反之亦然。

      优先级用整数表示,取值范围是1~10,一般情况下,线程的默认优先级都是5,但是也可以通

过setPriority和getPriority方法来设置或返回优先级。

调度策略:

      1.时间片

      2.抢占式:高优先级的线程抢占CPU

Java的调度方法:

      1.同优先级线程组成先进先出队列,使用时间片策略

      2.对高优先级,使用优先调度的抢占式策略

Thread类有如下3个静态常量来表示优先级: 

       MAX_PRIORITY:取值为10,表示最高优先级。

       MIN_PRIORITY:取值为1,表示最底优先级。

       NORM_PRIORITY:取值为5,表示默认的优先级。

线程状态

线程的状态:

      新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态

      就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了

运行的条件,只是没分配到CPU资源

      运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run()方法定义了线程的操作和功能

      阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执

行,进入阻塞状态

      死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束

多线程的概念

      多线程是指程序中包含多个执行单元,即在一个程序中可以同时运行多个不同的线程来执行不

同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

什么情况下需要多线程:

      1.程序需要同时执行两个或多个任务

      2. 程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等等

多线程的优点:

     1.提高程序的响应

     2. 提高CPU的利用率

     3.改善程序结构,将复杂任务分为多个线程,独立运行

多线程的缺点

    1.线程也是程序,所以线程需要占用内存,线程越多占用内存也越多

    2.多线程需要协调和管理,所以需要跟踪管理线程,使得cpu开销变大

    3.线程之间同时对共享资源的访问会相互影响,如果不加以控制会导致数据出错

线程同步

     多个线程同时读写同一份共享资源时,可能会引起冲突。所以引入线程“同步”机制,即各线程间

要有先来后到;

同步就是排队+锁:

       几个线程之间要排队,一个个对共享资源进行操作,而不是同时进行操作

       为了保证数据在方法中被访问时的正确性,在访问时加入锁机制

       确保一个时间点只有一个线程访问共享资源。可以给共享资源加一把锁,哪个线程获取了这把

锁,才有权利访问该共享资源。

同步锁:

     同步锁可以是任何对象,必须唯一,保证多个线程获得是同一个对象(用来充当锁标记).

同步执行过程:

      1.第一个线程访问,锁定同步对象,执行其中代码.

      2.第二个线程访问,发现同步对象被锁定,无法访问.

      3.第一个线程访问完毕,解锁同步对象.

     4.第二个线程访问,发现同步对象没有锁,然后锁定并访问.

在Java代码中实现同步

以下实现基于模拟卖票的案例

以下代码使用继承Thread方式实现

  第一种:使用synchronized(同步锁)关键字同步方法或代码块。

public class TicketThread extends Thread{
    static int number=10;//模拟有十张票
    static Object o=new Object();//同步锁对象
/*
        synchronized(同步锁对象){
        同步代码块
        }
        同步锁对象作用:用来记录有没有线程进入代码块,如果有线程进入代码块,那么其他线程不能进入代码块
                     直到上一个线程完成了代码块中的内容,释放锁后下一个线程才可以进入
        同步锁对象要求:
                可以是任意类的对象
                同步锁对象是唯一的(多个线程拿到的是同一个对象)
 */

    //模拟出票
    @Override
    public void run() {
            while(true){
               synchronized (o){
                   if (number >0) {
                       System.out.println(Thread.currentThread().getName()+"获得了第"+number+"张票");
                       number--;
                   }else {
                       break;
                   }
               }
        }
    }
}

   第二种:synchronized还可以放在方法声明中,表示整个方法为同步方法。

public class SynchronizedDemo extends Thread{
    static   int num = 10;//模拟有10张票
    Object o =new Object();
    @Override
    public void run() {
        while (true){
            if (num <= 0) {
                break;
            }
            print();
        }
    }

    /*
        synchronized修饰方法时,同步锁对象不需要我们指定
        同步锁对象会默认提供:
           1.非静态的方法--锁对象默认是this
           2.静态方法--锁对象是当前类的Class对象(类的对象,一个类的对象只有一个)
     */
    public static synchronized void print(){
        if(num>0){
            System.out.println(Thread.currentThread().getName()+"买到了第"+num+"张票");
            num--;
        }
    }
}

以下代码为测试代码:

public class TicketTest {
    public static void main(String[] args) {

        TicketThread ticket=new TicketThread();
        ticket.setName("窗口一");
        ticket.start();

        TicketThread ticket1=new TicketThread();
        ticket1.setName("窗口二");
        ticket1.start();
    }
}

以下代码使用实现Runnable方式实现

   使用synchronized(同步锁)关键字同步方法或代码块。
public class TicketTask implements Runnable{
    int number=10;
    Object o=new Object();
    public void run() {
        while(true){
            synchronized (o){
                if (number >0) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(Thread.currentThread().getName()+"获得了第"+number+"张票");
                    number--;
                }else {
                    break;
                }
            }
        }
    }
}

以下为测试代码:

public class TicketTest {
    public static void main(String[] args) {
        TicketTask task=new TicketTask();

        Thread thread=new Thread(task);
        thread.setName("窗口一");
        thread.start();

        Thread thread1=new Thread(task);
        thread1.setName("窗口二");
        thread1.start();
    }

}

Lock(锁)

      从JDK 5.0开始,Java提供了更强大的线程同步机制-通过显式定义同步锁对象来实现同步。同

步锁使用Lock对象充当。

    java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。

    ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,在实现线程安

全的控制中,可以显式加锁释放锁

public class TicketThread extends Thread{
    static int number=10;
    static ReentrantLock reentrantLock=new ReentrantLock();
    public void run() {
        while (true) {
           try {
               reentrantLock.lock();//0——1 加锁
               if (number > 0) {
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       throw new RuntimeException(e);
                   }
                   System.out.println(Thread.currentThread().getName() + "获得了第" + number + "张票");
                   number--;
               } else {
                   break;
               }
           }finally {
               reentrantLock.unlock();//1——0 释放锁
           }
            }
        }
        /*
    synchronized 和 ReentrantLock区别:

    synchronized是一个关键字,控制依靠底层编译后的执令去实现
    synchronized可以修饰一个方法,还可以修饰一个代码块
    synchronized是隐式的加锁和释放锁,一旦方法或代码块中运行结束或出现异常,会自动释放锁

    ReentrantLock是一个类,是依靠java代码去控制(底层有一个同步队列)
    ReentrantLock只能修饰代码块
    ReentrantLock需要手动的加锁,手动的释放锁,所以释放锁最好写在finally中,一旦出现异常,包证锁能释放

           */
    }

以下是测试代码:

public class TicketTest {
    public static void main(String[] args) {
        TicketTask task=new TicketTask();

        Thread thread=new Thread(task);
        thread.setName("窗口一");
        thread.start();

        Thread thread1=new Thread(task);
        thread1.setName("窗口二");
        thread1.start();
    }
}

线程通信

线程通信指的是多个线程通过相互牵制,相互调度,即线程间的相互作用。

涉及三个方法:

     wait一旦执行此方法,当前线程就进入阻塞状态,并释放同步锁对象。

     notify一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高

的那个。

     notifyAll一旦执行此方法,就会唤醒所有被wait的线程。

注意:

     wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。

案例一:两个线程交替打印1-100之间的数字

public class TicketThread extends Thread {
    static int number = 1;//模拟有十张票
    static Object o = new Object();//同步锁对象

    @Override
    public void run() {
        while (true) {
            synchronized (o) {
               o.notify();//唤醒等待的线程
                if (number <100) {
                    System.out.println(Thread.currentThread().getName() + ":" + number);
                    number++;
                } else {
                    break;
                }
                try {
                    o.wait();//让线程等待,会制动释放锁    notify(),wait()必须在同步代码块中使用,必须使用锁对象调用
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
public class TicketTest {
    public static void main(String[] args) {

        com.ffyc.javathread.threaddemo5.TicketThread ticket=new com.ffyc.javathread.threaddemo5.TicketThread();
        ticket.setName("窗口一");
        ticket.start();

        com.ffyc.javathread.threaddemo5.TicketThread ticket1=new com.ffyc.javathread.threaddemo5.TicketThread();
        ticket1.setName("窗口二");
        ticket1.start();
    }
}

案例二生产者/消费者问题

    生产者(Productor)将产品放在柜台(Counter),而消费者(Customer)从柜台处取走产品,生产者一次只能生产固定数量的产品(比如:1), 这时柜台中不能 再放产品,此时生产者应停止生产等待消费者拿走产品,此时生产者唤醒消费者来取走产品,消费者拿走产品后,唤醒生产者,消费者开始等待.

柜台

public class Counter {
    int num=1;

    //生产者线程
    public synchronized void add() throws InterruptedException {//锁对象是this
         if (num==0){
             this.notify();
             num=1;
             System.out.println("生产者生产了一件商品");
         }else {
             this.wait();
         }
    }

    //消费者线程
    public synchronized void sub() throws InterruptedException {//锁对象是this
      if (num>0){
          this.notify();
          num=0;
          System.out.println("消费者取走了一件商品");
      }else{
          this.wait();
      }
    }
    /*
    sleep() 和 wait() 的区别

    sleep():
        Thread中的方法
        sleep()方法经过设定的时间后会自动唤醒
        sleep()方法不会释放锁

    wait():
         锁对象中的方法
         wait后的线程,必须通过其他线程的唤醒(notify() / notifyAll() )
         wait方法会自动释放锁
     */
}

消费者

/*
消费者
 */
public class Consumer extends Thread{
    Counter counter;
    public Consumer(Counter counter) {
        this.counter=counter;
    }

    @Override
    public void run() {
        while(true){
            try {
                counter.sub();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

生产者

public class Producers extends Thread{
    Counter counter;
    public Producers(Counter counter) {
        this.counter=counter;
    }

    @Override
    public void run() {
        while(true){
            try {
                counter.add();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

以下是测试代码:

public class Test {
    public static void main(String[] args) {
        Counter counter= new Counter();

        Producers producers=new Producers(counter);
        producers.start();

        Consumer consumer=new Consumer(counter);
        consumer.start();
    }
}

新增创建线程方式

实现Callable接口与使用Runnable相比,Callable功能更强大些,其具有以下特性:

    1.相比run()方法,可以有返回值

    2.方法可以抛出异常

    3.支持泛型的返回值

    4.需要借助FutureTask类,获取返回结果

    5.支持泛型

public class SumTask <T>implements Callable<T> {
    @Override
    public T call() throws Exception {
        Integer n=0;
        for (int i = 0; i < 10; i++) {
            n+=i;
        }
        return (T)n;
    }
}
public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        SumTask<Integer> sum =new SumTask<Integer>();
        FutureTask<Integer> future=new FutureTask<Integer>(sum);
        Thread thread=new Thread(future);
        thread.start();

        Integer sumber=future.get();//获取call方法返回的执行结果
        System.out.println(sumber);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2278127.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTTP/HTTPS ⑤-CA证书 || 中间人攻击 || SSL/TLS

这里是Themberfue ✨上节课我们聊到了对称加密和非对称加密&#xff0c;实际上&#xff0c;单纯地非对称加密并不能保证数据不被窃取&#xff0c;我们还需要一个更加重要的东西——证书 中间人攻击 通过非对称加密生成私钥priKey和公钥pubKey用来加密对称加密生成的密钥&…

leetcode:205. 同构字符串(python3解法)

难度&#xff1a;简单 给定两个字符串 s 和 t &#xff0c;判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t &#xff0c;那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符&#xff0c;同时不改变字符的顺序。不同字符不能映射到同一个字…

从epoll事件的视角探讨TCP:三次握手、四次挥手、应用层与传输层之间的联系

目录 一、应用层与TCP之间的联系 二、 当通信双方中的一方如客户端主动断开连接时&#xff0c;仅是在客户端的视角下连接已经断开&#xff0c;在服务端的眼中&#xff0c;连接依然存在&#xff0c;为什么&#xff1f;——触发EPOLLRDHUP事件&#xff1a;对端关闭连接或停止写…

EMS专题 | 守护数据安全:数据中心和服务器机房环境温湿度监测

您需要服务器机房温度监测解决方案吗&#xff1f; 服务器机房是企业中用于存储、管理和维护服务器及其相关组件的设施。服务器机房通常位于数据中心内&#xff0c;是一个专门设计的物理环境&#xff0c;旨在确保服务器的稳定运行和数据的安全性。服务器机房主要起到存储和管理数…

运输层安全协议SSL

安全套接字层 SSL (Secure Socket Layer) SSL 作用在端系统应用层的 HTTP 和运输层之间&#xff0c;在 TCP 之上建立起一个安全通道&#xff0c;为通过 TCP 传输的应用层数据提供安全保障。 应用层使用 SSL 最多的就是 HTTP&#xff0c;但 SSL 并非仅用于 HTTP&#xff0c;而是…

网络安全面试题汇总(个人经验)

1.谈一下SQL主从备份原理&#xff1f; 答&#xff1a;主将数据变更写入自己的二进制log,从主动去主那里去拉二进制log并写入自己的二进制log,从而自己数据库依据二进制log内容做相应变更。主写从读 2.linux系统中的计划任务crontab配置文件中的五个星星分别代表什么&#xff…

51单片机 DS18B20温度储传感器

DS18B20温度传感器 64-BITROM&#xff1a;作为器件地址&#xff0c;用于总线通信的寻址&#xff0c;是唯一的&#xff0c;不可更改 SCRATCHPAD&#xff08;暂存器&#xff09;&#xff1a;用于总线的数据交互 EEPROM&#xff1a;用于保存温度触发阈值和配置参数 暂存器 单总线…

如何保证光谱相机的稳定性和可靠性

光学系统设计与制造 高质量光学元件&#xff1a;采用高精度研磨和镀膜的透镜、棱镜、光栅等光学元件。优质的透镜可以减少像差和色差&#xff0c;确保光线准确聚焦&#xff1b;高质量的镀膜能够提高光学元件的透光率&#xff0c;降低反射损失&#xff0c;并且增强对不同波段光…

【芯片封测学习专栏 -- 2D | 2.5D | 3D 封装的区别和联系】

请阅读【嵌入式开发学习必备专栏 Cache | MMU | AMBA BUS | CoreSight | Trace32 | CoreLink | ARM GCC | CSH】 文章目录 Overview线键合&#xff08;wire-bonding&#xff09;封装FOWLP2D封装2.5D 封装硅通孔(TSV)硅中介层无TSV的2.5D 3D封装 Overview 我们先要了解一下&…

Apache搭建https服务器

Apache搭建https服务器 REF: 使用OpenSSL自建一个HTTPS服务

element-ui textarea备注 textarea 多行输入框

发现用这个组件&#xff0c;为了给用户更好的体验&#xff0c;要加下属性 1. 通过设置 autosize 属性可以使得文本域的高度能够根据文本内容自动进行调整&#xff0c;并且 autosize 还可以设定为一个对象&#xff0c;指定最小行数和最大行数。:autosize"{ minRows: 3, ma…

图论1-问题 C: 算法7-6:图的遍历——广度优先搜索

题目描述 广度优先搜索遍历类似于树的按层次遍历的过程。其过程为&#xff1a;假设从图中的某顶点v出发&#xff0c;在访问了v之后依次访问v的各个未曾被访问过的邻接点&#xff0c;然后分别从这些邻接点出发依次访问它们的邻接点&#xff0c;并使“先被访问的顶点的邻接点”先…

基于vue框架的的校园心理咨询室系统63w37(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,咨询师,文章类型,心理文章,在线咨询,典型案例,线下预约,取消预约 开题报告内容 基于Vue框架的校园心理咨询室系统开题报告 一、研究背景与意义 随着社会的快速发展和竞争的加剧&#xff0c;校园中的学生面临着越来越多的心理压力…

Spring 6 第1章——概述

一.Spring是什么 Spring是一款主流的Java EE轻量级&#xff08;体积小、不需要依赖其它组件&#xff09;开源框架Spring的目的是用于简化Java企业级应用的开发难度和开发周期Spring的用途不仅限于服务端的开发&#xff0c;从简单性、可测试性和松耦合的角度而言&#xff0c;任…

基于vite+vue3+mapbox-gl从零搭建一个项目

下面是基于 Vite、Vue 3 和 Mapbox GL 从零搭建一个项目的完整步骤&#xff0c;包括环境搭建、依赖安装、配置和代码示例。 1. 初始化项目 首先&#xff0c;使用 Vite 快速创建一个 Vue 3 项目&#xff1a; npm create vuelatest vue3-mapboxgl --template vue cd vue3-mapbo…

Kibana:ES|QL 编辑器简介

作者&#xff1a;来自 Elastic drewdaemon ES|QL 很重要 &#x1f4aa; 正如你可能已经听说的那样&#xff0c;ES|QL 是 Elastic 的新查询语言。我们对 ES|QL 寄予厚望。它已经很出色了&#xff0c;但随着时间的推移&#xff0c;它将成为与 Elasticsearch 中的数据交互的最强大…

使用葡萄城+vue实现Excel

最终实现效果如下 包含增加复选框 设置公式 设置背景颜色等&#xff0c;代码实在太多 有需要可留言 第一步&#xff1a;创建表头 请使用官网提供的网址&#xff1a;在线 Excel 编辑器 | SpreadJS 在线表格编辑器 1.点击下方号&#xff0c;创建一个新的sheet页 默认新创建的she…

[系统安全] 六十一.恶意软件分析 (12)LLM赋能Lark工具提取XLM代码的抽象语法树(初探)

您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列。因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全、逆向分析和恶意代码检测,“系统安全”系列文章会更加聚焦,更加系…

Linux浅谈——管道、网络配置和客户端软件的使用

目录 一、管道 1、管道符 2、过滤功能 3、特殊功能 4、扩展处理 5、xargs命令扩展 二、网络配置 1、ifconfig查看网络信息 2、配置文件详解 网卡配置文件位置 3、systemctl查看网卡状态 4、systemctl启动/重启/停止网卡 三、客户端软件 1、什么是SSH 2、常用SSH终…

Oracle 深入学习 Part12: Managing Indexes (管理索引)

索引的分类 逻辑分类&#xff1a; 单列和多列&#xff1a; 单列索引&#xff08;single column&#xff09;&#xff1a;对单列数据建立索引。 复合索引&#xff08;concatenated&#xff09;&#xff1a;对多列数据建立索引。 唯一性&#xff1a; 唯一性&#xff08;unique…