多线程

1、线程,程序,进程的基本概念,及其它们之间的关系

进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的

线程是一个比进程更小的执行单位,一次进程可以产生多个线程,与进程不同的是同一个进程的线程共享进程的堆和方法区资源,而每个线程都用拥有各自的程序计数器,虚拟机栈和本地方法栈,所以系统产生一个线程时,负担要比进程小的多,就是因为如此,线程被称为轻量级的进程

2、为什么要使用多线程呢?

现在的系统动不动要求处理百万级千万级的数据量,使用多线程正是开发高并发系统的基础,利用好多线程技术可以大大提高系统高并发能力及性能

现在是多核CPU时代,多线程可以提高cpu利用率

3、使用多线程可能遇到的问题?

并发编程的目的就是提高程序的执行效率提高程序运行效率,但并发编程还是会导致一些问题:比如内存泄漏、

上下文切换,死锁,还有受限于硬件和软件的资源闲置问题

4、 线程的生命周期和状态

初始状态

运行状态

阻塞状态

等待状态

超时阻塞状态

5、线程死锁

多个线程同时处于被阻塞状态,而它们中的一个或者全部都在等待资源被释放,由于线程无期限的阻塞,因此程序不可能结束

实例

package com.hya.helloworld;

public class DeadLockDemo {
   private static Object resource1 = new Object();
   private static Object resource2 = new Object();

   public static void main(String[] args) {
       new Thread(()->{
           synchronized (resource1){
               System.out.println(Thread.currentThread()+"get resource1");
               try {
                   Thread.sleep(1000);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
               System.out.println(Thread.currentThread()+"wait get resource2");
               synchronized (resource2){
                   System.out.println(Thread.currentThread()+"get resource2");
              }
          }
      }

    ,"线程1" ).start();

       new Thread(()->{
           synchronized (resource2){
               System.out.println(Thread.currentThread()+"get resource2");
               try {
                   Thread.sleep(1000);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
               System.out.println(Thread.currentThread()+"wait get resource1");
               synchronized (resource1){
                   System.out.println(Thread.currentThread()+"get resource1");
              }
          }
      }

              ,"线程2" ).start();
  }


}

image-20201104193344413

死锁产生的四个条件:

互斥条件:该资源任意时刻只由一个线程掌握

请求与保持条件:一个进程请求资源而阻塞时,对已拥有的资源保持不放

不剥夺条件:线程已获得资源在未使用之前不能强行剥夺,只能等自己使用 完毕才能释放

循环等待条件:线程之间形成一种头尾相接的循环等待资源关系

如何避免死锁?

破坏循环等待条件,按排序申请资源,反序释放资源

package com.hya.helloworld;

public class DeadLockDemo {
   private static Object resource1 = new Object();
   private static Object resource2 = new Object();

   public static void main(String[] args) {
       new Thread(()->{
           synchronized (resource1){
               System.out.println(Thread.currentThread()+"get resource1");
               try {
                   Thread.sleep(1000);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
               System.out.println(Thread.currentThread()+"wait get resource2");
               synchronized (resource2){
                   System.out.println(Thread.currentThread()+"get resource2");
              }
          }
      }

    ,"线程1" ).start();

       new Thread(()->{
           synchronized (resource1){
               System.out.println(Thread.currentThread()+"get resource1");
               try {
                   Thread.sleep(1000);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
               System.out.println(Thread.currentThread()+"wait get resource2");
               synchronized (resource2){
                   System.out.println(Thread.currentThread()+"get resource2");
              }
          }
      }

              ,"线程2" ).start();
  }


}

6、为什么我们调用start方法是会执行run方法,为什么我们不能直接调用run方法?

因为在新建一个线程时,调用start方法会让此线程启动处于就绪状态,当分配到时间片时就能开始运行了,start方法为线程提供准备工作,线程会执行run方法。而直接调用run方法时,run方法只是线程中的一个普通方法而已,还是在主线程中执行

7、synchronized关键字(同步)

synchronized解决的是多个线程之间访问资源的同步问题,synchronized可以保证它所修饰的方法或代码块在任意时刻只能有一个线程执行

posted @ 2020-11-05 08:57  hya是p10  阅读(81)  评论(0)    收藏  举报