多线程的基本知识

184 阅读3分钟

什么是线程:

线程是操作系统能够进行原酸调度最小的单位,她被包含在进程之中,是进程的实际运作单位 .

在外面的电脑中cpu也有多线程的概念,一般为4核8线程和8核16线程等,也就是多线程.核就是类似大脑的存在,线程表示同时可以做的事.

作用:多线层既然能够同时做多件事情,也就意味着提高了程序的运行效率.

只要你想要让多个事情同时发生就需要用到多线程,也就相当于后台运行多个软件

并发和并行:

并发:在同一时刻,有多个指令在单个cpu上交替执行

并行:在同一时刻,有多个指令在单个cpu上同时执行

多线程的实现方式

1.继承Thread类的方式进行实现\

屏幕截图 2023-12-18 160931.png

public class myethread extends Thread{
    @Override
    public void run() {
        }
    }
}
public class thread {
    public static void main(String[] args) {
        myethread mt1 = new myethread();
        myethread mt2 = new myethread();
        mt1.setName("线程1");
        mt2.setName("线程2");
        mt1.start();
        mt2.start();
    }
}

start表示线程的开始

2.实现Runable接口的方式进行实现:

屏幕截图 2023-12-18 161007.png

public class myrun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            Thread t1 = Thread.currentThread();
            System.out.println(t1.getName()+" "+i);

        }
    }
}
public class thread2 {
    public static void main(String[] args) {
        myrun mr = new myrun();
        Thread t1 = new Thread(mr);
        Thread t2 = new Thread(mr);

        t1.setName("线程一");
        t2.setName("线程二");

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

这类方法也是要实现run方法,启动的时候需要把对象传递给Thread类(没有继承Thread)

3.利用Callable接口和future接口方法实现

屏幕截图 2023-12-18 161059.png

import java.util.concurrent.Callable;

public class mycall implements Callable<Integer> {
//这里的<Integer>表示结果返回的类型
    @Override
    public Integer call() throws Exception {
        int sum=0;
        for (int i = 0; i < 100; i++) {
            sum=sum+i;
        }
        return sum;
    }
}
public class thread3 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        mycall mycall = new mycall();
        FutureTask<Integer> ift = new FutureTask<>(mycall);
        //线程运行结果
        Thread t1 = new Thread(ift);
        t1.start();
        Integer sum = ift.get();
        System.out.println(sum);
    }
}

屏幕截图 2023-12-18 161128.png

总体也就按照有无返回结果分为两类

常用的成员方法

屏幕截图 2023-12-18 161146.png

Thread t1 = Thread.currentThread();

返回当前线程的对象,一般表示运行的地方就比如在mian方法中调用返回的是mian线程的对象,静态方法可以直接使用类名调用

t1.sleep(5000);

让当前线程在这里休眠5000毫秒,休眠后还需重新抢夺cpu的线程权

t1.setPriority(10);

一般情况下每个线程的优先级都是5(1,5,10),优先级表示该线程抢到CPU的概率 在setPriority中传递的就是优先级的大小

t2.setDaemon(true);

当非守护线程执行完毕之后,守护线程就会陆续结束(当理想型完成了,备胎就没有必要存在了)

屏幕截图 2023-12-18 170248.png

线程的生命周期

屏幕截图 2023-12-18 171702.png

每个线程想要执行下去就必须去不停地抢CPU的执行权

而run方法就是一个线程的全部生命

而如果在一个线程执行的时候突然被其他线程抢走了CPU执行权就有可能出现不符合预期的结果

同步代码块:

屏幕截图 2023-12-18 182049.png 运用这个方式就能够在某段代码中锁住一个线程了

@Override
public void run() {
    while (true){
        synchronized (dest.lock){
            if(dest.count==0){
                break;
            }else{
                if(dest.foodflag==1){
                    try {
                        dest.lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }else{

                    System.out.println("厨师做了一碗面");
                    dest.foodflag=1;
                    dest.lock.notifyAll();

                }
            }

锁也不止一种

屏幕截图 2023-12-18 195630.png

有兴趣的小伙伴也可以去了解一下