java多线程

Java线程

Java

 

1.进程

 进程:就是正在运行的程序,分配内存让应用程序能够运行。

Windows系统号称多任务(可以他同时运行多个应用程序).

  宏观上看:windows确实是允许了多个程序。

  微观上看:cpu快速切换执行任务,由于速度特别快,我们人感觉不到这个切换的过程。

 

2.线程:线程在一个进程中负责代码的执行,就是一个进程中的执行路径。

  疑问:没有学习线程,为什么代码可以执行?

      答:java程序在运行的时候,jvm会帮我们创建一个主线程来执行代码。主线程主要负责main方法中的代码执行。

一个java程序中至少有2个线程:

   一个是主线程只要负责main方法中的代码执行,一个垃圾回收器线程,负责垃圾回收。

 

3.多线程:在一个进程中多个线程同时执行不同的任务。"同时":单核cpu快速切换多个线程执行任务,速度特别快感觉不到切换。

  多线程的好处:

    1.解决一个进程中同时执行多个任务的问题。

    2.提高资源的利用率。、

  多线程的弊端:

    1.增加cpu的负担。不是线程越多越好。

    2.降低了一个进程中线程的执行。

    3.容易引发线程安全问题。

    4.出现死锁现象。

 

  //java中创建线程有两种方式:

       方式一:Thread(线程类)

         1.需要定义一个类来继承Thread类

         2.重写thread类中run方法,把自定义线程的任务代码写在run方法中.

           每一个线程都有自己的任务代码.jvm创建的主线程的任务代码就是main方法,自定义的线程的任务代码就写在run方法中,自定义的线程就需要来执行run方法中的代码,

         3.创建Thread的子类,并且调用start()方法开启线程

 

注意点:一旦线程开启了,会默认执行线程对象中的run方法,但是千万不要自己直接调用run方法,如果直接调用了run方法就和普通方法没有区别

java给线程加锁:

  方式一:同步代码块

         //锁对象可以是任意一个java中的对象

         //java中的任意一个对象都会有一个对象的状态,就可以通过对象的状态来作为锁的一个标识符.

         //statue = 0 表示锁是关闭 statue = 1 表示锁打开

          synchronized(锁对象){}

          同步代码块的使用注意点:

            1.任意一个对象都可以做锁对象

            2.如果你在同步代码块中调用了sleep方法,不会释放锁对象。

            3.只有真正的存在线程安全的时候才需要使用同步代码块,否则会降低执行效率。

            4.多线程操作锁对象必须是唯一的,否则无效。

 

    不知道什么时候安全,什么时候不安全?

    答:出现线程安全的问题根本原因:

          1.存在两个或两个以上的线程.并且线程之间共享着一个资源.

          2.多个语句操作了共享资源

  方式二:同步函数:

          用关键字synchronized 修饰函数

   同步函数是否有锁对象:有的.

            同步函数使用注意点:

              1.如果是一个非静态的函数,同步函数的锁对象就是调用方法的对象(this对象),如果是一个静态函数同步函数的锁对象是当前函数所属类的字节码文件(class对象).

              2.同步函数的锁对象固定,不能够自己来指定.

              3.同步函数是同步整个函数的代码.

 

           推荐大家使用:同步代码块.

           原因:

               1.同步代码块的锁对象可以由我任意指定,同步函数是固定的.

               2.同步代码块可以控制被同步的范围,同步函数必须是整个函数的所有代码都被同步.

           

    代码同步是可以解决线程安全问题,但是如果使用不当会导致线程死锁问题:

       A线程等B线程完成,B线程又在等A线程,结果两个人就一直等下去,这个时候造成了线程死锁.

 

线程死锁不一定会出现,有可能会出现.

  死锁对象的解决方案:没有方案,尽量避免发生.

 

     线程的定义方式二:

       1.自定义一个类实现Runable接口,接口中就会提供一个run方法

        2.实现Runable接口中的run方法.将线程中的任务写在run方法中

        3.创建Runable接口的实现类对象.

        4.创建一个Thread对象,并把Runable实现类创建的对象作为参数.

        5.调用Thread对象的start方法来开启线程

 

   问题:为什么Runable接口实现类的实现类的对象作为参数传递?

    为了让对象中的run方法能够在线程中的run方法中执行,也就是能够将对象中的run方法最为线程中的任务来执行.

推荐使用:第二种方式 实现Runable.

 

 

4.线程的通讯:一个线程完成自己的任务,去通知另外一个线程去完成另外一个任务.

    wait();等待 如果线程执行了wait方法,那么该线程就会处于一个等待状态,等待状态的线程必须要通过其他线程来调用notify方法来唤醒。

notify();唤醒 随机唤醒线程池。

notifyAll();唤醒所有等待的线程。

 

生产者和消费者.

wait和notify的使用注意点 :

    1.wait方法和notify方法是属性Object对象

    2.wait方法和notify方法必须在同步线程中执行

    3.wait方法和notify方法必须有锁对象来调用

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/jsjlxgf/p/6133045.html