黑马程序员——多线程笔记

------- <a target=_blank target="_blank" href="http://www.itheima.com">android培训</a>、<a target=_blank target="_blank" href="http://www.itheima.com">java培训</a>、期待与您交流! ----------

多线程

一、概念

进程:正在运行中的程序。一般在任务管理器中可以看到有很多正在执行的程序。CPU在快速的切换执行这些进程,CPU在一个时刻只执行一个进程

线程:就是进程中的独立控制单元,控制程序的运行。一个进程肯定至少有一个线程,当线程执行完后,这个进程(程序)也就执行完了

多线程:就是一个进程里面有两个以上的线程同时在运行,其中有一个主线程,其他的线程辅助主线程共同完成程序的执行。当主线程执行的时候,其它线程可以处理如网络访问,垃圾回收等这些事情,使程序工作更快

多线程是cpu在几个线程之间切换,速度非常快,所以我们感觉程序是同时运行的,其实不是,在一个时刻CPU只运行一个线程(这是单核情况,多核除外)

为什么要覆写run方法?

因为定义的线程类就用来存储线程运行的代码,该储存功能就是run方法,就像主线程要运行的方法要存在main方法里面一样,由虚拟机调用main

 

二、线程创建的2种方法

1、  继承Thread类创建线程,并覆写run方法

步骤:【1】创建线程,并覆写run方法

class TestThreadextends Thread{

   @Override

   public void run() {

      System.out.println("线程运行");

   }

}

【2】调用线程的start方法,开启线程,并让jvm调用run方法

TestThread t=new TestThread();

    t.start();

如果用t.run();来运行,则只有一个线程,主线程,和普通的对象调用方法一样,线程并没有开启,必须要用start()方法才能开启线程

   2、实现Runnable接口
      步骤:【1】定义类实现Runnable接口

            【2】覆写Runnable的run方法
            【3】通过Thread类建立线程对象

            【4】把Runnable接口的自雷对象传递该线程的构造函数

            【5】调用线程对象的start方法开启线程

三、线程的几种状态

1、  创建

2、  运行

3、  冻结
冻结分为:休眠(sleep)和等待(wait())。调用这两个方法的话,表示放弃了CPU的执行权,被唤醒了之后,则回到阻塞状态
如果调用wait()方法,则必须用notify()来唤醒线程

4、  销毁:调用stop方法,或者代码运行完

5、  阻塞:在等待CPU的执行权。具备运行资格,但没有执行权

四、获取线程的名称

线程对象可以调用getClass()来获取线程的名称。线程也可以自定义名称,通过传递名称的构造函数可以指定线程名称,也可以用setname()来设置
用Thread.currentThread()可以获取当前线程的名称,是静态的方法。

五、实现方式和继承方式的区别?

实现方式:避免了单继承的局限性,建议一般采用实现方式
继承方式:线程的代码房子Thread子类方法中,实现方式代码存放在接口的子类中

六、线程的安全问题

问题的原因:
    当多条语句操作一个线程共享数据时,一个线程对多条语句执行了一部分,还没执行完,另一个线程参与进来,导致了共享数据的错误。
解决办法:
    对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其它线程不可以参与进来。通过同步代码块可以解决这个问题
synchronized(对象){
需要被同步的代码
}
即,在会产生安全问题的代码块,用synchronized进行同步,在一个时刻只有一个线程在里面执行,所以不会产生安全问题,不会把共享数据弄错
同步的前提:必须有两个以上的线程,必须是多个线程使用同一个代码块,但是同步之后会消耗一些资源,性能有一点影响

七、         同步函数

把synchronized做为修饰符修饰函数,那么这个函数就具备了同步的功能,同步函数传递的参数对象用的是同一个对象(锁)this,这样才会同步成功

八、静态函数的锁

静态进内存时,内存中没有本类对象,但是一定有字节码文件对象,类名.class,该对象类型是Class

synchronized(Demo.class){}

九、单例设计模式

懒汉式和恶汉式。懒汉式在加载的时候会产生线程安全问题,可以通过同步来解决这个问题,加同步的方式可以用双重判断来解决,使用的锁是该类所属的字节码对象

延迟加载的单例设计模式

如下:

public static SinglegetInstance(){

      if(s==null){

         synchronized (Single.class) {

            if(s==null)

                s=newSingle();

         }

      }

      returns;

   }

十、死锁

同步中嵌套同步,但是锁不同,一定要会写死锁


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑马程序员多线程练习题主要包括两个问题。第一个问题是如何控制四个线程在打印log之前能够同时开始等待1秒钟。一种解决思路是在线程的run方法中调用parseLog方法,并使用Thread.sleep方法让线程等待1秒钟。另一种解决思路是使用线程池,将线程数量固定为4个,并将每个调用parseLog方法的语句封装为一个Runnable对象,然后提交到线程池中。这样可以实现一秒钟打印4行日志,4秒钟打印16条日志的需求。 第二个问题是如何修改代码,使得几个线程调用TestDo.doSome(key, value)方法时,如果传递进去的key相等(equals比较为true),则这几个线程应互斥排队输出结果。一种解决方法是使用synchronized关键字来实现线程的互斥排队输出。通过给TestDo.doSome方法添加synchronized关键字,可以确保同一时间只有一个线程能够执行该方法,从而实现线程的互斥输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [黑马程序员——多线程10:多线程相关练习](https://blog.csdn.net/axr1985lazy/article/details/48186039)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值