• 多线程


    基础概念

    多线程:
         进程:一个程序中至少一个进程,一个进程至少一个线程。
        
         用户线程,正常情况下创建
         守护线程:需要手动创建
        
         线程是通过调用start()方法准备启动
        
         线程调度!
        
    线程的创建方式:两种,
         1.Thread类派生,覆盖run()
         2.实现Runnable接口

    线程调度

    image

    什么是线程调度?线程是不可控的,那么如何干预线程的执行?
         -等待:
             让某一个线程进入等待状态,等到条件满足后,被其他线程唤醒
             等待需要在同步环境,未持锁则报错
             等待后被唤醒,需重新经过持锁状态,然后回到就绪状态,等待资源分配
         -休眠:
             是让当前线程进入休眠状态,这是Thread的静态方法,休眠只能自己响
             1.至少消耗指定时间,(等待资源分配)
             2.休眠不可以被唤醒,休眠必须有参数!
            
         -让步:
             1.不建议使用优先级、礼让!因为最终结果不可控!
             2.使用,先设优先级,再启动线程
             3.让步是不可控的
             4.没有经过阻塞,直接回到就绪状态
            
         -合并线程:
             1.是让并行线程,变为串行状态
             2.先执行,再合并
             3.什么情况下要合并线程?
                 某个线程要等到另外一个线程结果时,需要合并,已等待前面的结果。
            
         -守护线程:(用户线程的区别--所有用户线程执行完毕后,其他所有守护线程killed)
             1.当用户线程全部执行完毕后,守护线程立即停止,无论他执行到哪儿
             2.守护线程,先设置,再执行。
             应用情况:定时任务;清理日志;定时同步数据

        
        
         -唤醒:

    一个对象可以持有多个锁吗?所以:线程之间争夺锁资源唯一

    线程同步
         1.同步(底层看不到)
             同步方法:保护整个方法当中所有数据的安全
             同步代码块:保护方法当中某个区域的数据安全,意义在于让那些不需要考虑到同步的数据先执行,以提高运行效率。
             一般来说:属于线程本身数据区域的数据和  读的数据
         2.非静态同步,同步的锁是对象锁,只有相同实例才存在同步
         3.静态同步,锁的是类,只要是这个类,就会触发同步。
         4.不建议大家混杂同时使用静态和非静态锁。
        
         容器基本都是多线程!

    内部封装好的安全类:

    ByteArrayInputStream---FilterInputStream
    StringBuffer
    Collections

    Note:

    --即使是线程安全的类,也应该特别注意,因为操作的线程之间仍然不一定安全。
         线程安全类的安全仅仅局限于:它本身,但是其他操作不一定!

    基本概念:

    死锁:--解决,按照预定义的顺序获取锁。
         1.两个线程互相持有对方的锁,且互相等待,这种情况下,有小概率发生死锁。
         2.避免死锁的策略,就是按照相同的顺序获取锁,并释放锁。

    原子化:
         一个整体、数据完整
         --要么都成功,要么都失败。


    wait() otify() otifyAll()三个方法:

    看下面的代码,这个代码执行的话会报错,java.lang.IllegalMonitorStateException

    上网查了一下,明白了。

    1>当前线程不含有当前对象的锁资源的时候,调用obj.wait()方法;
    2>当前线程不含有当前对象的锁资源的时候,调用obj.notify()方法。
    3>当前线程不含有当前对象的锁资源的时候,调用obj.notifyAll()方法。


    生产消费者模型

    生产消费者模型:
         1.消息队列,服务发布和服务消费。。。。
         消费者:
             1.先来后到的顺序
             2.消费者需要的东西,多种多样
             3.消费者需要的东西,可以不需要一次性全部获取
             4.如果生产者的能力达到上限,那么需要等待。
         生产者:
             1.生产者需要尽可能按照消费的先后顺序完成生产
             2.生产者还必须保证所有的生产都要完成
             3.如果没有消费者的消费需求,则需要等待。

    //定义队列对象(+泛型)

    import java.util.LinkedList;

    public class MyQueue<T> {
         private LinkedList<T> queue;
         private final int DEFAULT_CAPACITY = 20;
         private int maxSize;
         public MyQueue() {
             this.maxSize = DEFAULT_CAPACITY;
             this.queue = new LinkedList<T>();
         }
         public MyQueue(int size) {
             this();
             this.maxSize = size;
             this.queue = new LinkedList<T>();
         }
         public synchronized void put(T t) {
             if (queue.size()>=this.maxSize) {
                 System.out.println("队列已满...等待");
                 try {
                     this.wait();
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }
             queue.add(t);
             //唤醒的是当前对象wait()的线程
             this.notifyAll();
         }
         public synchronized T get() {
             if (queue.size()<=0) {
                 System.out.println("队列为空...等待");
                 try {
                     this.wait();
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }
             this.notifyAll();
             return queue.removeLast();
         }
        
         public synchronized int getSize() {
             return this.queue.size();
         }
    }

    //生产者、消费者持有同一个线程对象

    //生产线程

    public class ProducerThread implements Runnable{
         private final MyQueue q;
         private final String message;
         public ProducerThread(final MyQueue q,final String message){
             this.q = q;
             this.message = message;
         }
         @Override
         public void run() {
             //每隔2秒生产一个
             while(true){
                 try {
                     Thread.sleep(500);
                     q.put(Thread.currentThread()+":"+message);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
         }
      

    //消费者线程

    public class ConsumerThread implements Runnable{
         private final MyQueue q;
         public ConsumerThread(final MyQueue q){
             this.q = q;
         }
         @Override
         public void run() {
             // TODO Auto-generated method stub
             while(true){
                 try {
                     Thread.sleep(1000);
                     Object obj = q.get();//消费
                     System.out.println(obj);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
         }
    }

    //测试


    public class Test {

        public static void main(String[] args) {
             // TODO Auto-generated method stub
             MyQueue q = new MyQueue();
             //多生产者
             new Thread(new ProducerThread(q, "生产者1")).start();
             new Thread(new ProducerThread(q, "生产者2")).start();
             new Thread(new ProducerThread(q, "生产者3")).start();
            
             //多消费
             new Thread(new ConsumerThread(q)).start();
             new Thread(new ConsumerThread(q)).start();
             new Thread(new ConsumerThread(q)).start();
         }

    }


    Volatile:关键字,不建议使用!

    ??

    有限的情形下使用volatile变量替代锁。
         1.对变量的写操作不依赖于当前值。




    final型的变量是禁止修改的,也就不存在线程安全的问题。

    //继承自父类的属性,this.属性指向super.属性,都是指向父类的同一个属性(效果等效)


    反射的应用

    --Java.lang.reflect.*
    应用:
         1.反射调用方法———将方法作为对象,而不再是类名
         2.field.setAccessible(true);--暴力更改访问机制,访问private
         3.constructor.newInstance()

    面向对象编程
         开发期间:类是构成Java程序的单位,Java程序通过类来组织其结构
         运行期间:对象是Java程序在运行时的单位,运行期间的Java程序是通过多个对象之间的相互作用关系来完成需求,动态。
        
    null:空指针,内存地址的一个值,指空,不存在。
    垃圾回收机制GC:是一个独立的巡查线程,GC是一个定时任务,隔一段时间执行一次。

    基本数据类型在栈内存中开辟空间,同时直接将具体数值(而不是地址)保存在栈中
         --int numb = null;报错
    引用类型在栈中开辟空间,同时在堆中开辟空间,创建对象,将对象地址保存在栈中。
    内存模型,原理?



  • 相关阅读:
    用instr 直接取最右端的点的位置:
    ASP FSO操作文件(复制文件、重命名文件、删除文件、替换字符
    Ubuntu 16.04系统下安装RapidSVN版本控制器及配置diff,editor,merge和exploer工具
    Ubuntu 16.04系统下开机提示“无法应用原保存的显示器配置”
    Ubuntu 16.04系统下出现E: 无法下载 http://ppa.launchpad.net/fcitx-team/nightly/ubuntu/dists/xenial/main/binary-amd64/Packages 404 Not Found
    Ubuntu 16.04系统下软件中心Software闪退解决办法
    UEditor富文本WEB编辑器自定义默认值设置方法
    HTML5 移动页面自适应手机屏幕四类方法
    Ubuntu 16.04系统下apt-get和dpkg区别
    jQuery相同id元素 全部获取问题解决办法
  • 原文地址:https://www.cnblogs.com/macro-renzhansheng/p/12556865.html
Copyright © 2020-2023  润新知