首页 > 其他分享 >01_多线程

01_多线程

时间:2023-06-06 16:45:45浏览次数:43  
标签:01 Thread void 线程 new 多线程 方法

多线程

一、进程与线程

1.1、进程:

进程:是正在运行的程序

  • 是系统进行资源分配和调用的独立单位

  • 每个进程都有它自己的内存空间和系统资源

 

1.2、线程:

在一个进程内部,可以执行一个任务,也可以执行多个任务

线程:是进程中的单个执行顺序控制流,是一条执行路径

  • 单线程:一个进程中如果只有一条执行路径,则称为单线程程序

  • 多线程:一个进程中如果有多条执行路径,则称为多线程程序

 

二、多线程的实现方式

1.1、方式1:继承Thread类

  • 定义一个类MyThread类

  • 在MyThread类中重写run()方法

  • 创建MyThread类对象

  • 启动线程

两个问题:

  • 为什么要重写run()方法?

    因为run方法是用来封装被线程执行的方法

  • run方法和start方法的区别?

    run:封装线程执行的代码,直接调用,相当于普通方法的调用

    start:启动线程;然后由JVM调用此线程的run方法

 

1.2、Thread类中获取和设置线程名称的方法

void setName(String name):设置线程名称 String getName():返回线程名称

 

三、线程调度

线程有两种调度模型:

  • 分时调度模型

  • 抢占式调度模型

Java是抢占式

 

四、设置和获取线程名称

设置线程名称:myThread1.setName("线程1");

获取线程名称:myThread1.getName();

//static Thread currentThread() :返回对当前正在执行的线程对象的引用 System.out.println(Thread.currentThread().getName());

 

五、线程优先级

最小:1

最大:10

默认值:5

方法:

//获取线程的优先级 System.out.println(myThread1.getPriority()); //5 System.out.println(myThread2.getPriority()); //5

//设置线程优先级:max:10;min:5 myThread2.setPriority(10); myThread1.setPriority(1);

 

六、线程控制

//static void sleep(long millis):使当前正在执行的线程暂停指定的毫秒数

//void join():等待这个线程死亡

//void setDaemon(boolean on):将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机退出

 

七、线程的生命周期

 

八、多线程实现方式

8.1、方式2:实现Runnable接口

  • 定义一个MyRunnable类实现接口

  • 在MyRunnable中重新run方法

  • 创建MyRunnable类的对象

  • 创建Thread类的对象,把MyRunnable对象作为构造方法的参数

  • 启动线程

 

8.2、多线程的实现方式有两种:

  • 继承Thread类

  • 实现Runnable接口

8.3、相比继承Thread类,实现Runnable接口的好处:

  • 避免了Java单继承的局限性

  • 适合多个相同程序的代码去处理同一资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想

 

九、同步代码块

锁多条语句操作共享数据,可以使用同步代码块实现

  • 格式:

synchronized (任意对象){
   //多条语句操作共享数据的代码
   //               t1进来后,就会把这段代码给锁起来
   if (ticket > 0){
       //通过sleep方法来模拟出票时间
       try {
           Thread.sleep(100);
      } catch (InterruptedException e) {
           throw new RuntimeException(e);
      }
       System.out.println(Thread.currentThread().getName() + "正在出售第" + ticket + "张票");
       ticket--;
  }
}
  • synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成一把锁

  • 弊端:当线程很多时,因为每个线程都会判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

 

十、同步方法

同步方法:就是把synchronized关键字加到方法上

  • 格式:

private synchronized void sellTicket() {
   
}
  • 同步方法的锁对象是this

同步静态方法:就是把synchronized关键字加到静态方法上

  • 格式

private static synchronized void sellTicket() {

}

同步静态方法的锁对象是

  • 类名.class

 

十一、线程安全的类

public class ThreadDemo {
   public static void main(String[] args) {
       //线程安全
       StringBuffer sb = new StringBuffer();
       //线程不安全
       StringBuilder sb2 = new StringBuilder();


       //以下两个被Collections替代了
       //线程安全
       Vector<String> v = new Vector<>();
       //线程不安全
       ArrayList<String> strings = new ArrayList<>();

       //线程安全
       Hashtable<String, String> ht = new Hashtable<>();
       //线程不安全
       HashMap<String, String> hm = new HashMap<>();

       //static <T> list<T> synchronizedList(list<T> list):返回由指定列表支持的同步(线程安全的)列表
       List<String> strings1 = Collections.synchronizedList(new ArrayList<String>());

  }
}

 

 

十二、Lock锁

Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作

Lock中提供了获得锁和释放锁的方法:

  • void lock();获得锁

  • void unlock();释放锁

Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化

ReentrantLock的构造方法

  • ReentrantLock():创建一个ReentrantLock的实例

 

 

十二、死锁

在Java多线程程序中,死锁是一种非常常见的问题。死锁是指两个或多个线程互相持有彼此需要的资源并且互相等待,从而导致程序无法继续执行下去的一种情况。

例如,如果线程 A 持有锁 1,并尝试去获得锁 2,而线程 B 此时持有锁 2,尝试去获得锁 1,那么这两个线程就会进入死锁状态。因为线程 A 需要锁 2 才能释放锁 1,而线程 B 需要锁 1 才能释放锁 2。

为了避免死锁,可以使用以下方法:

  1. 避免共享资源:尽量避免线程之间共享同一个资源,或使用同步机制来避免冲突。

  2. 加锁的顺序一致性:尽量让所有线程按照相同的顺序获取锁,例如所有线程都先获取锁1,再获取锁2。

  3. 超时机制:在获取资源的时候,设置超时机制,如果超过一定时间还没有获取到资源,就放弃。这样可以避免线程无限等待。

  4. 用 tryLock():使用可重入锁(ReentrantLock)的 tryLock() 方法,如果未能获取到锁则返回 false,避免长时间阻塞。

  5. 避免嵌套锁:尽可能避免使用嵌套锁,如果必须使用,则一定要确保加锁的顺序一致。

标签:01,Thread,void,线程,new,多线程,方法
From: https://www.cnblogs.com/suliull/p/17460983.html

相关文章

  • 1018 Public Bike Management
    题目:ThereisapublicbikeserviceinHangzhouCitywhichprovidesgreatconveniencetothetouristsfromallovertheworld.Onemayrentabikeatanystationandreturnittoanyotherstationsinthecity.ThePublicBikeManagementCenter(PBMC)keep......
  • 【汽车处理器】TMS5701115CPGEQQ1 Hercules™ TMS570 ARM® Cortex®-R
    TMS5701115CPGEQQ116/32位RISC闪存微控制器(MCU)是一个用于安全系统的高性能汽车级微控制器系列。其采用的安全架构包括锁步中的双CPU、CPU和内存内置自检(BIST)逻辑、闪存和数据SRAM上的ECC、外设存储器上的奇偶校验以及外设I/O上的回路功能。TMS570器件集成了可提供高效1.66......
  • 2023年5月31日吴曦远202283820011实验五
    task1_1.pycode:withopen('data1.txt','r',encoding='utf-8')asf:data=f.readlines()n=0print(data)forlineindata:ifnotline.strip()=='':n+=1print(n)output:note:ifdelet"not"......
  • widnows2012 r2上安装iis 报错,提示找不到原文件位置的解决办法。
    服务器win2012安装.NetFramework3.5失败的解决方法安装一个或多个角色、角色服务或功能失败。找不到源文件。请在尝试在新的“添加角色和功能”向导会话中安装角色、角色服务或功能,然后在向导的“确认”页中单击“指定备用源路径”以指定安装所需的源文件的有效位置。目标服......
  • zookeeper-01:软件的安装
    ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。  以上内容摘自baidu百科!   下面......
  • 「杂题乱写」AGC 001
    「杂题乱写」AGC001点击查看目录目录「杂题乱写」AGC001A|BBQEasyB|MysteriousLightC|ShortenDiameterD|ArraysandPalindromeE|BBQHardF|WideSwapA|BBQEasy排序奇数项求和,贪心正确性显然。B|MysteriousLight发现可以分割成若干个等边三角形,......
  • word2019发布博客到博客园,解决word配置时出现的问题
    一开始按照网上的教程设置了博客URL,类似https://www.cnblogs.com/xxxxxxx/services/metaweblog.aspx这种,没有成功,再去查发现2021年之后就不支持这种URL地址了。改用设置-基本设置中的MetaWeblog访问地址,但还是提示word无法注册您的账户,也检查了用户名和密码就是登录时的用户名密......
  • 001.对工作的一些反思
    1、田忌赛马的反思1、田忌赛马的故事告诉我们,做事的顺序不同,效果差距很大。先做什么,后做什么,顺序不可颠倒。2、关于我这个人1、从秃子来说,我有些地方,比如说:多干活少说话,多干活说明我是个勤劳的人,少说话是因为,话多容易热是非。2、为什么李林林说我飘了?宁老师一走,别......
  • ORA-01555:snapshot too old: rollback segment number X with name "XXXX" too small
    ORA-01555:snapshottooold:rollbacksegmentnumberXwithname"XXXX"toosmall在查询快照的时候select*fromtesttableasoftimestampto_timestamp('2023-04-0322:00:00','yyyy-mm-ddhh24:mi:ss')提示错误ORA-01555:snapshottooold:r......
  • 585. 2016年的投资
    【题目】写一个查询语句,将2016年(TIV_2016)所有成功投资的金额加起来,保留2位小数。对于一个投保人,他在2016年成功投资的条件是:   他在2015年的投保额(TIV_2015)至少跟一个其他投保人在2015年的投保额相同。   他所在的城市必须与其他投保人都不同(也就是说......