线程的创建

进程:就是正在运行的程序  (一个进程可以有多个线程),分配内存让应用程序能够运行。

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

  宏观上看:Windows确实运行了多个程序

  围观上看:cpu快速做了切换操作,快速执行任务

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

java程序在运行的时候,java虚拟机会帮我们创建一个主线程来执行代码,主线程主要负责main里面的代码

一个java程序里面,至少有两个线程,一个是主线程,主要负责main方法的执行,另外一个是垃圾回收器线程,主要负责垃圾回收

多线程:在一个进程中,多个线程同时执行不同的任务,(就是单核cpu在做快速的切换,多个线程执行任务)

多线程的好处:

     1.可以解决一个进程中同事执行多个任务的问题

     2.提高资源的利用率

多线程的弊端:

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

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

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

     4.容易出现死锁

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

    方式一: Thread (线程类)

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

                 2.重写Thread类中的run方法,把自定义线程的任务代码写在run方法中,每一个线程都有自己的任务代码,java虚拟机创建的主线程的任务代码就是main方法,自定义的线程的任务代码就写下run方法中,自定义的线程就需要来执行run方法中的代码

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

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

线程的生命周期:

        创建线程(new子线程类)——>等待运行状态(只有cpu的等待资格,没有执行)——>运行状态(具备cpu的执行权,具备cpu的等待权)

 ——>结束

线程如果执行sleep或者wait方法,那么这个时候线程会处于阻塞状态,如果是sleep方法,如果超过了睡眠时间线程会立马进入等待运行状态,如果是wait,需要通过其他的线程来唤醒

线程常用的方法:

     Thread (String name)初始化线程名字

      getName()               返回线程的名字

      setName(String name)设置线程对象名字

      sleep()                       线程睡眠指定毫秒数

      getPriority                     获取主线程的优先级,默认线程的优先级是5,

      setPriority(int newPriority)设置线程的优先级,虽然设置了线程的优先级,但是具体的实现取决于底层的操作系统的实现(最大的优先级是10,最小的优先级是1,一般默认是5)

       currentThread()返回cpu正在执行的线程对象

出现了线程安全问题,数据操作不安全

     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.实现Runbale接口的run方法,将线程中的任务写在run方法中

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

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

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

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

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

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

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

              notify()方法来唤醒

notify();唤醒 随机唤醒一个

notifyAll();唤醒所有的等待

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

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

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

原文地址:https://www.cnblogs.com/2016yjl/p/6126492.html