• java多线程


    多线程就是多个任务同时执行

    进程是对操作系统就是多任务执行,每个进程都有自己的代码和数据空间,进程是资源分配的最小单元,一个进程包括至少一个线程

    线程多个线程共享代码和数据空间,线程之间切换消耗较小,线程是cpu调度的最小单位

    好程序的三高:高可用(数据不会出错)高性能(效率高)高并发(多用户并发)

    多线程的创建方式

    1继承Thread类 重写run()方法

           执行类直接继承Thread类,内部重写run()方法,自身调用start()方法启动多线程

    public class Threaddemo01 extends Thread {   //1继承Thread

        public static void main(String[] args) {

           Threaddemo01 th=new Threaddemo01();   //3创建对象以及线程

           th.start();                                //4线程就绪

           for(int i=0;i<10;i++){                  //5主方法的另一线程同步执行

               System.out.println("哭");

           }

        }

        @Override

        public void run() {                           //2重写run()方法

           for(int i=0;i<100;i++){

               System.out.println("笑");

           }

        }

    }

    Thread中

    start()方法启动线程

                  run()方法定义多线程的线程体 通过重写实现不同的代码

                  run()需要通过start()启动,否则就变为方法的调用,并非多线程

                  Thread属于lang包

    2实现Runnable接口,重写run()方法 --推荐

    优点通过类实现接口,能够避免使用extends

    缺点是Runnable没有直接的start方法 没有返回值和异常抛出

    主要步骤:

    1创建多线程类实现接口,并重写run()  注意 :并非是使用多线程的类

    2创建多线程类的对象

    3开启线程需要创建Thread的静态代理

    在静态代理中导入多线程类的对象,通过start()方法启动

    new Thread(多线程对象,String).start();   (创建启动同步执行,能够命名线程)

    普通创建

    public class Threaddemo2 implements Runnable { //实现Runnable接口      

        public static void main(String[] args) {   

           Threaddemo2 th=new Threaddemo2();        //创建引用

           Thread rh =  new Thread(th);               //接入静态代理

             rh.start();                                  //代理就绪

           for(int i=0;i<10;i++){

               System.out.println("哭");

           }

        }

        @Override

        public void run() {                             //重写run方法

           for(int i=0;i<100;i++){

               System.out.println("笑");

           }

        }

    }

    对于只在单个类中使用的多线程类,可以写成成员内部类

    对于只在单个方法中使用的多线程类,可以写成局部内部类

    简化创建

    针对单次并直接使用的多线程体通过匿名类或lambda表达式实现并启动

    不再需要另外创建实现Runnable的类

    public class Threaddemo3 {

        public static void main(String[] args) {

           new Thread(new Runnable(){                 //匿名类

               public void run() {

                  for(int i=0;i<100;i++){

                      System.out.println("笑");

                  }

               }

           }).start();

           for(int i=0;i<10;i++){

               System.out.println("哭");

           }

        }

    }

    new Thread(()->                                      //直接使用lambda表达式

    {for(int i=0;i<100;i++)System.out.println("笑");}).start();

           for(int i=0;i<10;i++){

               System.out.println("哭");

           }

     

    需要练习龟兔赛跑

     3实现Callable接口,重写call()方法

    优点是可以返回值并抛出异常   属于juc高级多并发处理(了解即可) 

    1         创建Callable的实现类,在实现类中重写call()方法,在call()中写入多线程体

    class 类名 implements Callable<范型>{

           public 返回值类型 call(){

                  多线程的内容

                  return 返回值

    }

    }

    2         创建线程

    ExecutorService 引用名=Executors. newFixedThreadPool (线程容量);

    创建多线程类的对象,获取对象名

    Future<返回值类型> 返回值引用名1=引用名.submit(对象名);

    Future<返回值类型> 返回值引用名2=引用名.submit(对象名);

    引用名.shutdown();

    线程状态

    新生状态 : new,每个线程都有自己的运行空间

    就绪状态 : start(),代表线程具有可运行的能力,在就绪队列中等待cpu调度

    运行状态 : cpu把时间片分配给某个线程,这个线程就就行运行状态

    阻塞状态 : sleep()..

    终止状态 : 执行完毕

    注意:      一个线程一旦阻塞状态,阻塞解除进入就绪状态并非继续执行

    一旦一个线程以终止,无法恢复,如果创建开启,也是新的线程

    终止状态的方法

           1)正常执行完毕

    2)强制结束 stop(),destroy(),方法已过时,不推荐使用

    3)通过标识进行控制--推荐(flag等)

    进入就绪状态

    1.start()

    2.阻塞状态结束

    3.yield()                礼让线程,当前线程进入就绪状态

    4.线程切换,被切换的线程进入到就绪状态

    进入阻塞状态

    sleep()    用于将问题放大增加问题发生的可能性   模拟网络延时

    wait()

    join( thread )  被插队,等待插队线程执行完毕

    IO操作

    Thread中的方法

           sleep(毫秒)   静态方法

                  写在多线程中,控制执行线程进入阻塞状态若干时间

           用于将增加出现问题的可能性   模拟网络延时

           yield() 静态方法

                  当前线程执行到Thread.yield()时回到就绪排队状态,相当于0秒sleep

           join()

                  插队线程       用于将目标线程插到其他线程的前面

                  目标线程调用该方法,将调用该方法的代码插入到其他线程的代码中

    使得其他线程等待目标线程先执行完成

    getStatic()   

           获取指定线程的线程状态返回一个枚举类

    枚举类Thread.State是Thread的内部枚举类,通过该类进行比较

           setPriority(int)

           设置线程的优先级 优先级包括1-10 默认为5

           Thread定义了静态优先级常量

           Thread.MAX_PRIORITY=10

           Thread.MIN_PRIORITY =1

        Thread.NORM_PRIORITY=5

    getPriority()

    获取线程的优先级

          

    线程安全

    多线程同时操作同一份资源,可能出现线程不安全的问题

    synchronized同步锁处理方法 

    锁的范围太大,效率低,锁的范围太小锁不住

    1同步方法 效率较低,简单

    同步静态方法

          同步成员方法

           直接在成员方法或成员变量之前加上synchronized修饰符

           锁静态方法,锁类的class对象都是锁类,锁住了这个类的所有对象

    2同步块

           同步块锁的内容就是要线程修改的内容  也相当于钥匙

    synchronized(this|类名.calss|资源(成员属性)){锁住的代码}

    多线程执行到同步块时,观察锁对象是否被其他线程调用,若调用则等待

    A需要锁的代码在静态方法中时,同步块需要将类全部锁上

           Synchronized(类名.class){锁住的代码}

           锁住的内容包括类的静态内容和所有该类的对象 静态环境中不能使用this

    B需要锁的代码在成员方法中,同步块需要将对象锁住

    Synchronized(this){锁住的代码}

    锁住的内容是对象的所有成员属性

    C需要锁的内容是属性,可以直接锁属性

    Synchronized(属性){锁住的代码}

    锁一定要锁不变的资源内容,锁的就是地址(自定义类型对象地址)

    double check 双重检查 在锁内之前添加if判断 效率高,使得锁的范围小

  • 相关阅读:
    ubuntu安装mysql并修改编码为utf-8
    ubuntu16.04安装jdk1.8
    解决 Can't Connect to MySQL Server on IPAddress (10061) 的问题
    使用开源数据库客户端DBeaver连接DB2数据库
    Windows下使用console线连接思科交换机
    win7安装JDK6
    Python将excel文件从xls转换为xlsx
    Windows使用Gitblit搭建Git服务器
    B树、B-树、B+树、B*树
    必须熟悉的vim快捷键操作
  • 原文地址:https://www.cnblogs.com/javaxiaobu/p/11026359.html
Copyright © 2020-2023  润新知