多线程

进程和线程这块去看os这块的进程知识#

我的os小笔记

这本书很好

 

 

 

 

 

 

 

继承Thread类#

 

 

 实现多线程的时候,要注意

  • 需要继承Thread类
  • 必须重写run方法,核心执行的逻辑
  • 线程在启动的时候不要直接调用run方法,而是要通过start()方法来进行调用
复制代码
public class ThreadDemo extends Thread{
    public void run(){
        for(int i = 0; i < 10; i++){
            // coding
        }
    }

    public static void main(String[] args){
        ThreadDemo ThreadDemo = new ThreadDemo();
        ThreadDemo.start();
        for(int i = 0; i < 5; i++){
            // coding
        }
    }
}
复制代码

如果像下面这么写,只会运行main这个线程

复制代码
public class ThreadDemo extends Thread{
    public void run(){
        for(int i = 0; i < 10; i++){
            // coding
        }
    }

    public static void main(String[] args){
        ThreadDemo ThreadDemo = new ThreadDemo();
        ThreadDemo.run();
        for(int i = 0; i < 5; i++){
            // coding
        }
    }
}
复制代码

实现Runnble接口(推荐使用,因为java单继承,将继承关系留给最需要的类;方便共享资源)#

 

使用了代理设计模式#

  • 实现了runnable方法
  • 重写run方法
  • 创建Thread类,将刚刚创建好得到runnbale的自类实现作为thread类的构造参数
  • 通过Thread.start()进行启动
  • 使用runnable接口之后不需要给共享变量添加static关键字,每次创建一个对象
复制代码
public class TicketRunnable implements Runnable{

    private int ticket = 5;

    public void run(){
        for(int i = 0; i < 100; i++){
            if(ticket > 0){
                // coding
            }
        }        
    }

    public static void main(String[] args){

        TicketRunnable ticket = new TicketRunnable();        
        TicketThread t1 = new Tread(ticket);
        TicketThread t2 = new Tread(ticket);
        TicketThread t3 = new Tread(ticket);
        TicketThread t4 = new Tread(ticket);

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

    }
}
复制代码

线程声明周期#

  • 新生状态,创建好当前线程对象之后,没有启动之前(调用start方法前)
  • 就绪状态,准备开始执行,并没有执行,表示调用start方法之后
  • 运行状态,当前进程获取CPU资源后,就绪对立中的线程抢占CPU
  • 死亡状态,运行中线程正常执行完所有代码逻辑,因为异常情况导致程序结束
  • 阻塞状态,发生某些异常情况,导致当前线程无法顺利执行下去,紧入阻塞状态,阻塞结束后进入就绪状态

五状态模型#

 

如何进入死亡状态#

  • 正常结束
  • 人为中断执行,stop方法
  • 程序抛出未捕获的异常

如何进入阻塞状态#

  • sleep方法
  • 等待io资源

暂停/停止线程的方法#

  • sleep,当前线程处于阻塞状态
  • yield,暂停正在进行的线程,允许其他线程进行,不阻塞,如果没有其他执行的线程,当前线程会立马执行
  • join,当某个线程等待另一个线程执行结束后,才继续执行,调用该方法的线程在此前执行完毕,等待调用该方法的线程执行完毕后执行
  • stop,强制结束线程,暴力结束

同步#

  • 每次启动线程对象的时候都会创建自己对象的属性值,没有真正实现共享
  • 将共享对象,共享变量设置成static
  • 每次访问共享对象时,数据不一致
  • 此时使用线程同步,即加锁

 

同步的前提#

  • 必须有两个或两个以上的线程
  • 必须是多个线程使用同一资源
  • 必须保证同步中只能有一个线程运行

CAS 无锁式同步机制#

同步代码块synchronized(共享资源,共享对象,需要Object的子类)

复制代码
public class SleepTest implements Runnable{

    private int ticket = 5;

    public void run(){
        for(int i = 0; i < 100; i++){
            try{
                Thread.sleep(200);
            }catch(Exception e){
                e.printStackTrace();
            }
            synchronized(this){
                if(ticket > 0){
                    // coding
                }                
            }            
        }        
    }

    public static void main(String[] args){

        TicketRunnable ticket = new TicketRunnable();        
        TicketThread t1 = new Tread(ticket, "A");
        TicketThread t2 = new Tread(ticket, "B");
        TicketThread t3 = new Tread(ticket, "C");
        TicketThread t4 = new Tread(ticket, "D");

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

    }
}
复制代码

synchronized,同步方法,不需要指定共享对象

复制代码
public class SleepTest implements Runnable{

    private int ticket = 5;

    public void run(){
        for(int i = 0; i < 100; i++){
            this.sale();    
        }        
    }

    public void synchronized sale(){        
        try{
            Thread.sleep(200);
        }catch(Exception e){
            e.printStackTrace();
        }
        if(ticket > 0){
            // coding
        }                                        
    }

    public static void main(String[] args){

        TicketRunnable ticket = new TicketRunnable();        
        TicketThread t1 = new Tread(ticket, "A");
        TicketThread t2 = new Tread(ticket, "B");
        TicketThread t3 = new Tread(ticket, "C");
        TicketThread t4 = new Tread(ticket, "D");

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

    }
}
复制代码

同步监视器#

synchronized(obj){}中的obj称为同步监视器

 

 生产者-消费者#

 get和set加同步锁

 加信号量同步

 wait(),进入阻塞状态,notify,进入唤醒状态

JUC,Java Util Concurrent#

1.5以后出的新功能

posted @   BigBender  阅读(110)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2019-12-30 B1012. 数字分类
2019-12-30 B1008. 数据元素循环右移问题
2019-12-30 函数的概念
2019-12-30 编译原理--引论(四)
2019-12-30 编译原理--引论(三)
2019-12-30 2012年英语一小作文
2019-12-30 函数连续性
点击右上角即可分享
微信分享提示
主题色彩