• 多线程


    进程和线程这块去看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以后出的新功能

  • 相关阅读:
    php生成二维码遇到的问题
    ua判断页面在什么终端/系统打开
    js实现复制文字到剪切板
    jquery 实现表单数据转化为对象格式
    [转]关于setTimeout()你所不知道的地方
    关于性能优化
    关于event loop
    JS数据结构与算法--双向链表
    JS数据结构与算法--单向链表
    JS数组去重
  • 原文地址:https://www.cnblogs.com/YC-L/p/14213493.html
Copyright © 2020-2023  润新知