java基础——多线程总结

来源:互联网 发布:下载qq软件 编辑:程序博客网 时间:2024/05/16 18:05


在讲多线程的时候,必须明确什么是进程,进程就是应用程序在内存中开辟的一片存储空间,而线程就是进程的一条执行路径,负责执行进程中的控制单元,多线程就是一个进程有多条执行路径。

一个进程至少有一条线程,有一条的就是单线程,有多条线程的就是多线程程序。

多线程的好处:可以让部分代码同时执行,在一般情况下提高了效率,其实,最实际的时多线程是提高了用户体验

多线程在执行的时候,是由cup随机分配执行权的,其实在某一个时刻只有一条线程在执行(单核),但是cup会在这些线程之间做着快速的切换。所以会给我们觉得是在同时执行的。

java的JVM一运行就至少会有两条线程在执行,一条是负责main的主线程,一条是负责垃圾回收的线程,垃圾回收线程是守护线程,main线程一结束,他也就结束了

 

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

第一种:继承Thread类

1、        继承Thread类

2、        复写run方法

3、        通过创建子类来创建线程

4、        调用start方法开启线程,并调用run方法

第二种:实现Runnable接口

1、        实现runnable接口

2、        复写run方法

3、        创建子类对象

4、        通过Thread类创建线程,并将子类对象作为实际参数传递给Thread类的构造函数

5、        调用start方法开启线程,并调用run方法

为什么要创建线程呢?

1、        创建线程是了执行指定的代码也就是说每一个线程都有自己的任务

2、        创建多线程是为了执行多个指定的任务

3、        每一个任务都有自己的存放空间,主线程的任务代码存放在主函数里面,自定义的线程任务存放在run方法中

第二种创建线程的方式有什么好处呢?

  首先,通过实现Runnable接口的方式,避免了单继承的局限性,而且    更加的面向对象,将任务和线程对象分隔,降低了线程对象和任务的耦 合性

调用start方法和调用run方法有什么不同?

  调用start方法会现开启线程然后在调用run方法,如果直接调用run      方法的话是不会开启线程的而是接着调用了方法

多线程的并发时的安全问题?

  安全问题产生的原因:

1、        多条线程同时访问到了共享的数据

2、        一条线程中的部分代码同时访问了共享数据

既然有安全问题那么怎么解决呢?

  首先安全问题产生是由于有多个任务在同时处理共享数据,那么要解决这个问题,只要让共享数据在某个时刻只有一个任务在处理他就哦了

所以可以使用同步来完成:synchronized(任意对象){需要被同步的代码}

同步的好处:解决了多线程并发访问时的安全问题

同步的弊端:降低了程序的运行效率

如果加了同步还是有安全问题怎么办呢?这个时候可以看下加的同步是否使用了同一个锁

上面说的是同步代码块,除了这个还有同步函数,同步函数使用的锁是this关键字,静态的同步函数使用的锁是   类名.class

所以同步代码块使用的锁是任意的,而同步函数使用的锁则是固定的

同步在单例设计模式上的使用:主要是延时加载

  使用双重判断来提高代码的效率

class Single

{

  private static  Single s = null;

  private Single s(){};

  public static voidgetInstance(){

  if(s==null){

  synchronized(Single.class){

       if(s==null)

             s=newSingle();

             }

       return s;

  }

  }

}

 

同步还有另一个弊端就是死锁,可能产生死锁的场景是同步嵌套

线程-0

synchronized(a){

  synchronized(b){}

}

线程-1

synchronized(b){

  synchronized(a){}

}

 

 

线程之间的通信:

  就是多个线程在同时处理同一个资源,但是任务却不一样

主要应用的就是等待唤醒机制

  wait()    notify()   notifyAll()这些必须都定义在同步里面

wait:可以让当前线程等待,其实就是让线程临时存储到线程池中,线程池的 标识就是锁

notify:唤醒线程池中的任意一个

notifyAll:唤醒线程池中的所有的等待的线程

 

注意wait和sleep的区别

  wait必须被唤醒,而sleep会在一定时间后自动醒,wait会释放锁,sleep则不会释放锁,但都会释放cup的执行权,wait可以指定时间也可以不指定时间,sleep则必须指定时间

 

在JDK1.5之前,这些所都是看不见的,比较难理解,到了JDK1.5之后,java更新了同步,将Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。

出现了新的拿锁和释放锁的方法

  lock()    unlock()    await()      signal()   signalAll()

lock():拿锁

unlock:释放锁

await:等待

signal:唤醒

signalAll:唤醒所有

 

结束线程的两种方式:

  第一种就是让run方法运行完结束

第二种就是捕获InterruptedException 运行时异常,中断当前线程

 

 

 

 

 

 

0 0