首页 > 代码库 > 线程_基本

线程_基本

 

 

进程:正在运行的程序称作为一个进程。进程负责了内存空间的划分

windows号称是多任务的操作系统,那么windows是同时运行多个应用程序么?

  宏观角度:windows确实是在同时运行多个应用程序

  微观角度:cpu是做了一个快速切换执行的动作,由于速度太快,所以我们感觉不到在切换而已

单核的cpu在一个时间片中只能执行一个应用程序

各个应用程序其实是在做cpu资源争夺战

 

线程:负责代码的执行

多线程:在一个进程中有多个线程在执行不同的任务

线程负责了代码的执行,以前没有线程,为什么代码可移执行?

  任何一个java程序,jvm在运行的时候都会创建一main线程执行main方法中的所有方法

一个java应用程序至少有几个线程?

  至少有两个线程,一个是主线程,负责main方法事物执行,一个是垃圾回收器,负责了回收垃圾。

与其说是进程在做cpu的资源争夺战,不如说是线程在做cpu的资源争夺战

多线程的好处:

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

  2.提高了资源的利用率(将没有用尽资源利用起来)

弊端:

  增加了CPU的负担

  降低一个进程中线程的执行概率

  会引发线程安全问题

  出现死锁现象

如何创建多线程:

  创建线程的方式:

   方式一:

    1.自定义一个类继承Tread类

    2.重写Thread类的run方法

      疑问:重写run方法的目的是什么?

    每个线程都有自己的任务代码,jvm创建的主线程的任务代码就是main方法中的所有代码,自定义线程的任务代码就写在run方法中,自定义线程负责了run方法中代码

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

      一个线程一旦开启,那么线程就会执行run方法中的代码,run方法千万不能直接调用,直接调用run方法就相当于调用了一个普通方法而已

    主线程和自定义线程是交替进行的

 

线程的生命周期:

cpu的等待资格

cpu的执行权

 

  创建状态(将线程类对象new出来时):没有cpu等待资格,没有cpu执行权

  (调用start方法)

  可运行的状态(具备等待cpu的资格,不具备cpu的执行权)

  (得到cpu的执行权,若被抢夺了cpu的执行权,返回上一状态)

  运行状态(具备cpu的执行权,也具备cpu的等待资格)

  (完成任务)

  死亡状态(没有cpu的等待资格,没有cpu执行权)

 

临时阻塞状态(运行状态下的线程,一旦执行了sleep或者waitfangfa之后,那么该线程会进入临时阻塞状态下,如果线程是调用了sleep进入阻塞状态,那么线程一旦超过了指定的睡眠时间,就会重新进入可运行状态,如果调用了wait方法进入临时阻塞状态,那么需要该线程唤醒其他线程才可以重新进入可运行状态)不具备等待资格

 

技术分享

 

线程常用的方法

  thread(String name); 初始化线程的名字

  getName()  返回线程的名字

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

  sleep()  线程睡眠指定的毫秒数  是一个静态的方法 哪个线程执行了sleep方法,那么就是哪个线程睡眠

  getPriority()  返回当前线程的优先级 默认线程的优先级是5

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

  currentThread()  返回cpu正在执行的线程对象 该方法是一个静态方法,注意:哪个线程执行了currentThread()代码,就返回那个线程的对象

 

thread 子类 的run方法为什么不能抛出异常?

  因为thread类的run方法没有抛出异常,所以继承父类的子类也不能抛出异常,run方法属于重写,重写的方法抛出的异常要小于或者等于父类抛出的异常

 

 

非静态的成员变量,非静态的成员变量数据是在每个对象中都会维护一份数据的

 

在什么情况下会出现线程安全问题:

  1.存在两个或者两方以上的线程,并且线程之间共享一个数据资源

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

 

多线程的好处:

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

  2.提高了资源的利用率

 

多线程的弊端:

  1.增加了cpu的负担

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

  3.出现了线程安全问题

  4.会引发死锁现象

 

 

 

线程安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题

  java线程同步机制的方式:

    方式一:同步代码块:

      同步代码块的格式:

        synchronized(锁对象){

        需要被同步的代码  

        }

  同步代码块要注意的事项:

    1.锁对象可以是任意的一个对象,

      任意的对象都可以作为锁对象。凡是对象内部都维护了一个状态的,java同步机制就是使用了对象中的状态作为了锁的标识  (用一个字符串也可以锁住)

    2.在同步代码块中调用了sleep方法并不释放锁对象

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

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

  方式二:同步函数  使用synchronized修饰一个函数

    同步函数的注意事项:

      1.如果是一个非静态的同步函数的锁  对象是this对象  如果是静态的同步函数的锁  对象是当前函数所属的类的字节码文件(class对象)(在方法区创建一个对象后,系统将相应类进行分解,得到的方法属性封装到一个class对象上)

 

推荐使用:同步代码块

  原因:

    1.同步代码块的锁对象可以由我们随意指定,方便控制。同步函数的锁对象是固定的,不能由我们来指定。

    2.同步代码块可以很方便控制需要被同步代码的范围,同步函数必须是整个函数的所有代码都被同步了。

 

java中的同步机制,解决了线程中的安全问题,也同时引发了死锁现象

死锁现象 出现的根本原因::

  1.存在两个或者两个以上的线程

  2.存在两个或者两个以上的共享资源

 

死锁解决的方案:没有方案,只能尽量避免的发生

  

自定义线程的创建方式二:

  1.自定义一个类实现runnable接口

  2.实现Runnable接口的run方法,把自定义线程的任务定义在run方法上

  3.创建runnable的实现类对象,

  4.创建thread类的对象,并且把Runnable实现类的对象作为一个参数传递进行

  5.调用thread对象的start方法开启一个线程

 

问题1:请问runnable实现类的对象是线程对象吗?-------线程必须有start方法

  Runnable实现类的对象并不是一个线程对象,只不过是实现了Runnable接口的对象而已

  只有Thread及thread的对象才是属于线程对象

问题2:为什么要把runnable实现类的对象作为实参传递给Thread对象?作用是什么?

  作用是把Runnable实现类的对象的run方法作为了线程的任务代码去执行

 

自定义线程的创建,推荐第二种。实现Runnable接口的

原因:因为java是单继承多实现的

 

 

 

 

 

 

 

 

  

线程_基本