线程的概念

本文介绍了并发和并行的概念,以及在Java中进程和线程的区别。线程是进程中的执行单元,Java使用抢占式调度策略。多线程可以提高效率并减少相互影响。在Java程序中,至少有main主线程和垃圾回收线程并发运行。
摘要由CSDN通过智能技术生成
  • 并发和并行

并发:指两个和多个事件在同一个时间段内发生,CPU高速切换交替去执行任务。

并行:指两和多个事件在同一时刻发生,多个CUP同时执行多个任务。

  • 进程

一个应用程序的执行就是一个进程。 每一个进程都有一 个独立的内存空间, 是系统运行程序的基本单位。在电脑中下载的应用程序存储在磁盘中(ROM) 执行时是在内存中执行的(RAM)。

(2)进程与进程之间的关系

每个进程内存是独立并且不共享的。

线程(相当于进程(软件)中的功能)

线程是进程中的一一个执行单元,负责当前进程中的程序的执行,-个进程中至少有一个线程。-个进程中拥有多个线程,这个应用程序也可以称之为多线程程序。

(2)线程的调度

分时调度:所有线程轮流拥有CUP的使用权,平均分配每个线程占用CPU的时间。

抢占式调度:优先让优先级高的线程使用CUP,如果线程的优先级相同,CPU就会随机选择一个线程执行。 Java使用的是抢占式调度。

举例:在银行的一个窗口排队办理业务时,如果你是金卡用户,就会优先办理你的业务。

(3) 多线程的好处

1.效率高

2.多个线程之间互不影响

四、Java主线程;

在Java程序运行中,我们使用jave 类名命令执行程序时。会先启动JVM,JVM就是一个应用程序它的执行就是一个进程。JVM接着执行main方法,main方法就是一个主线程,同时还会再启动一个垃圾回收线程,回收垃圾。

因此,java程序中至少有两个线程在并发运行,一个是main主线程,一个是垃圾回收线程。并且执行main方法后,代码是从下到下

依次执行。

main方法的是JVM进行调用,之后main方法会进入到栈内存中,此时JVM会开辟一个道 (主线程)让cpu去执行main方法。 这样main方法就被cup进行调度执行了。

一、创建线程
方式1:通过继承Thread类
步骤:
(1)创建一个类,继承Thread类,并且重写run方法。(run方法里面的代码就是我们创建的线程后执行的代码)
 (2)创建Thread的子类对象
(3)调用start()方法开启线程。自动执行run方法

方式2:通过实现Runnable接口(常用)
步骤:
(1)创建Runnable接口的实现类并且重写run方法
 (2)创建实现类的对象
(3)将实现类的对象传递给Thread构造器,创建Thread的对象。
(4)通过调用start()方法开启线程,执行run方法

二、设置线程的名称
方法1:通过Thread中的SetName方法设置名称
方法2:通过构造器设置线程名称


方式1和方式2区别:
1.方式1只能单继承
2.方式2扩展性好

扩展
方式3:通过匿名内部类去创建线程

三、线程名称的获取
  方法1、通过Thread类中的getName()方法获取名称。
  方法2、(1)通过Thread类中的静态的currentThread()方法获取的当前正在执行线程的引用
      (2)通过该引用调用getName()方法获取到线程名称


四、线程安全问题
   多个线程在操作同一个资源时,没有遵守原子性导致结果和预期不同
   例如:两个线程卖了同一张票
   此时,使用线程同步的方式去解决这个问题
五、线程同步
四种方式:
    1.同步代码块
    格式: synchronized(同步锁){
    //会发生线程安全问题的代码
    }
    同步锁:一般随便用一个对象来充当锁,要保证锁是唯一的
    原理:当一个线程在执行同步代码块中代码时,必须获取锁才能执行代码。
          保证每次执行代码的线程只有一个

    2.同步方法
    用synchronized修饰的方法
    把会发生线程安全问题的代码放在同步方法中去
    同步锁:当前类对象:this

     注意:用此方法解决同步问题时,不能使用继承Thread的方式去创建线程
        原因:因为会创建多个子类对象,所以同步方法锁this表示的对象不同,锁不唯一

      3.静态同步方法
      用synchronized修饰的静态方法
      同步锁:当前类的class对象

      4.使用lock锁
      使用步骤:
       (1)创建ReentrantLock对象
       (2)在会发生同步问题的代码前调用 lock()方法锁住代码
       (3)在代码后调用unclock()方法释放锁

六、线程的状态
  new(新建):创建Thread线程对象后,还没有调用start()方法
  Runnable(可执行):执行了start()方法后,此时线程可能不会立即执行,等CPU调度后才会执行,处于一个就绪的状态。
  blocked(锁阻塞):线程执行后,没有获取到同步锁,此时线程处于锁阻塞状态。等待其他线程释放锁,如果抢到了锁,恢复Runnable状态
  Waiting(无限等待):执行了wait()方法后,线程处于一个无限等待状态。必须等待其他线程执行notify或者notifyAll方法将其唤醒。
  Timed_waiting(计时等待):执行sleep(time)或者wait(time)方法后,线程开始进入计时等待,时间到了后自动醒来。也可被notify或者notifyAll方法将其唤醒。
  Terminated(死亡):线程执行完run方法后,自动就销毁了。

  线程中常用的方法:
  1.static sleep(time):Thread类中静态方法。让线程在指定时间内释放CPU资源,如果此时线程拥有对象锁,它就不会释放。
  2.wait();是Object类中的方法。会释放CPU资源,如果此时线程拥有锁,会释放对象锁。
  3.notify:是Object类中的方法。唤醒一个等待时间最长的线程。只能唤醒一个线程。
  4.notifyAll:是Object类中的方法。唤醒所有等待的线程。

  注:一般将wait、notify、notifyAll方法放在同步代码块中,使用锁对象去调用,保证线程的同步。

  顾客点菜----->wait()--->等待厨师制作--->notify---->叫顾客吃饭了
  顾客是一个线程
  厨师是一个线程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值