8/17 学习博客 多线程的基本知识

进程包含一个或多个线程,进程是资源调度的基本单位,线程是执行调度的基本的单位。线程的创建和销毁效率都比进程高。Java开发一般就是线程为主。

线程的几种常用创建方式:

比如:
1.继承Thread类重写run方法。
2.实现Runnable接口 重写run方法。
3.继承Thread类重写run方法,用内部隐藏函数。
4.实现Runnable接口 重写run方法,用内部隐藏函数。
5.lambda表达式 ()->{}

还有等等

线程的几种特性就是 id name 优先级 状态 是前台线程还是后台线程

其中前台线程会影响进程的结束,后台线程就不会。默认创建的都是前台线程
通过
t.setDaemon(true);
//设置t为后台线程

java线程终止是通过加快run方法的执行来的,有强制结束的方法但不建议 所以我们就通过标志符来判断run方法什么时候结束

1.我们自己手动设置比如isQuit = false 然后 while(!isQuit){ 这样来判断

对于lambda表达式创建 有需要注意的点:
就是lambda有个捕获变量 作用域是到上一类,所以如果()里面用的变量是被捕获的,那么这个变量他要求是final 不可修改 。 所以我们的isQuit要作为一个成员变量,那么这样lambda他就不是访问捕获变量的语法了,就不受final限制。

2.Thread内部有一个现场标志位,用于判断是否结束 通过t.interrupt(); 来终止

需要注意的是 如果只是单纯的interrupt
该线程还是会继续运行, 假装没听见 所以我们需要加一个break来彻底终止

 Thread t = new Thread(()->{
            //Thread内部有一个现场标志位,用于判断是否结束
           while(!Thread.currentThread().isInterrupted()){
               System.out.println("线程工作中");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
            
                   e.printStackTrace();
                   //做一些其他工作完成之后在结束
                   System.out.println("其他操作");
                   break;

               }

           }


        });
        t.start();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("让t线程终止");
        t.interrupt();
    }

t.join() 让主线程阻塞等待t线程的执行完毕

接着线程安全问题

就比如count++ 在cpu里面是分为3个步骤 load内存加载到cpu add加 save保存到内存

这时候两个并发的编程都执行这个count++,由于这个线程调度执行的随机性所以最后就会出现 结果的覆盖丢失。

这就是因为这个++在cpu不是原子操作

这也说明引发线程安全的两个原因
1.最主要就是线程调度执行的随机性(抢占式)
2.两个线程对同一变量做修改。

解决的话就是通过加锁方式来保障原子性

这里就通过synchronized锁 (要注意synchronized后括号里的对象要是同一个)
这样 锁对象一样才会触发锁竞争,不同则依旧并行

锁竞争就是 t1先加锁在执行的时候,t2也访问这个资源同时就触发了锁竞争,t2的lock操作就会阻塞到t1的unlock操作后才能执行完毕

posted @ 2026-08-30 11:57  曾章吉的浩吧  阅读(2)  评论(0)    收藏  举报