java多线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程相关的知识,希望对你有一定的参考价值。

第十七天知识点总结

一、多线程

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

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

宏观上看:windows确实是运行了多个程序。

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

 

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

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

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

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

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

 

多线程:在一个进程总多个线程同时执行不同的任务。同时:单核CPU快速切换多个线程执行任务,速度特别快,人感觉不到切换

多线程的好处:

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

     2.提高了资源的利用率

 

多线程的弊端:

      1.增加了CPU的负担,不是线程越多越好。

      2.降低一个进程中的程序的执行效率。

      3.容易引发线程安全。

      4.出现死锁现象。

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

方式一:Thread(线程类)

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

2.重写Thread类中的run方法,把自定义线程的任务代码写在run方法中。每一个线程都有自己的任务代码,jvm创建的主线程的任务代码就是main方法,自定义的线程的任务代码就写在run方法中。

3.创建thread子类,并且调用start方法来开始线程。

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

方式二:

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

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

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

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

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

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

     为了让对象中的Run方法能够在线程中的Run方法中执行,就是能够将对象中的Run方法作为线程中的任务来执行。

推荐使用:第二种创建方式

 

线程的生命周期:

1.new子线程类()创建线程

2.等待运行状态(只有CPU的等待资格没有执行权)

     ↓↑

3.运行状态(具备CPU的执行权,具备CPU的等待权)

运行---->堵塞(线程如果执行sleep或者wait方法,那么这个时候线程会处于一个阻塞状态,如果是sleep方法,如果超过了睡眠时间,线

程会立马进入等待运行状态,如果是wait需要通过其他线程来唤

    Sleep方法

)------------------>等待运行状态

4.结束

 

 

线程中的常用方法:

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

 getName()           返回线程的名字

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

 Sleep()               线程睡眠指定的毫秒数

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

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

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

Java给线程加锁:

方式一:同步代码块

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

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

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

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

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

 

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

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

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

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

方式二:同步函数用关键字synchronized修饰函数

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

同步函数的使用注意点:

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

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

 

 

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

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

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

 

代码同步是可以解决线程安全问题

但是如果使用不恰当就会导致线程线程死锁问题:

A线程等B线程完成,B线程又在等A线程 结构两个人就一直等下去,就造成了线程死锁。

 

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

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

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

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

 

生产者和消费者。

Waitnotify的使用注意点:

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

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

3.Wait方法和notify方法必须由锁对象来调用

 

 

 

以上是关于java多线程的主要内容,如果未能解决你的问题,请参考以下文章

什么是JAVA的多线程?

Java多线程 1.认识Java线程

Java多线程 5.栅栏

java 如何实现多线程

java中啥叫做线程?啥叫多线程?多线程的特点是啥

Java多线程-Java多线程概述