当前位置:网站首页 > Java教程 > 正文

java多线程详细教程



🏠个人主页: 黑洞晓威
🧑个人简介:大家好,我是晓威,一名普普通通的大二在校生,希望在CSDN中与大家一起成长。

🎁如果你也在正在学习Java,欢迎各位大佬来到我的博客查漏补缺呀,如果有哪里写的不对的地方也欢迎诸佬指正啊。

@[toc]

程序:一段静态的代码

进程:运行中的代码

线程:程序的一种执行路径

在java语言中:

线程A和线程B, 内存共享。但是 独立一个线程一个栈

  1. 创建一个继承与Thread的子类
  2. 重写Thread的run()方法
  3. 创建Thread类子类的对象
  4. 通过这个对象调用start()

注意:

  • t.run() 不会启动线程,只是普通的调用方法而已。不会分配新的分支栈。(这种方式就是单线程。)
  • t.start() 方法的作用是:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码任务完成之后,瞬间就结束了。
    这段代码的任务只是为了开启一个新的栈空间,只要新的栈空间开出来,start()方法就结束了。线程就启动成功了。启动成功的线程会自动调用run方法,并且run方法在分支栈的栈底部(压栈)。
  • run方法在分支栈的栈底部,main方法在主栈的栈底部。run和main是平级的。匿名创建Thread类子类

匿名创建Thread类子类


Thread中的常用方法

  1. currentThread():静态方法,返回当前代码的线程
  2. getName():获得当先线程的名字
  3. setName():设置当前线程的名字
  4. yield():释放当前cpu的执行权
  5. join():在线程a中调用线程b的join();则线程a进入阻塞状态,等线程b结束后结束阻塞状态
  6. sleep(Long militime)让当前线程阻断指定的militime毫秒,此时为阻塞状态
  7. isAlive();判断线程是否存活

线程的优先级

MAX_PRIORITY:10

MIN_PRIORITY:1

NORM_PRIORITY:5(默认)

注意:高优先级抢占低优先级线程cpu,但不代表一定先执行完高优先级再执行低优先级

实例:三个窗口卖一百张票



  1. 创建一个实现了Runnable接口的类
  2. 重写run();
  3. 创建实现Runnable类的对象;
  4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象;
  5. 通过Thread类的对象调用start();

优势:实现的方式没有类的单继承的局限性

实现的方式更适合处理多个共享数据的类型



  1. 问题:买票过程中出现了重票错票
  2. 原因:当某个线程尚未操作完成时,其他线程参与过来,也操作车票

关键字synchronized(同步监视器)

  1. 操作共享数据的代码就是需要同步的代码
  2. 同步监视器俗称锁,任何一个类的对象都可以充当锁
  3. 要求:需要同步的线程要共用同一把锁
  4. 操作同步代码时只能运行一个线程,相当于一个单线程,但能保证安全问题

实现方法的synchronized


补充:在实现Runnable接口创建多线程的方式中,可以考虑用this充当对象

​ 在继承thread创建多线程的方式中,慎用this充当对象,可以考虑用当前类充当对象

如果操作共享数据的代码在一个方法中

  1. 实现接口多线程使用同步方法

  1. 继承thread多线程同步方法需要调用静态方法

    public static synchronized void show(){}

总结:
  1. 同步方法依然涉及到同步监视器,只是不显示说明。
  2. 非静态同步方法的同步监视器是:this

​ 静态同步方法的同步监视器是:当前类


lock与synchronized的区别

synchronized在执行完同步代码后,自动释放同步监视器。

lock需要手动启动同步(lock),同时结束同步也需要手动实现(unlock)

死锁


练习

银行有一个账户.

有两个储户分别向同一个账户存3000元,每次存1000,存三次.每次存完打印账户余额.



例子:使用两个线程交替打印1-100

涉及到的三个方法:

wait():一旦执行此方法,当前线程进入阻塞状态,并释放同步监视器

notify():会唤醒被wait的一个线程,如果有多个线程wait则比较优先级

notifyAll():唤醒所有被wait的线程

注意:

  1. 上述三个方法必须在同步代码块或同步方法中使用
  2. 上述方法默认为this.方法,要与synchronized保持一致

不懂的地方:上面代码的wait()与notify()放在循环外无法实现通讯

sleep与wait的异同

相同点:都进入阻塞状态

不同点:1.声明的位置不同:Thread类中声明的sleep,wait在object类中声明

​ 2.调用要求不同:sleep可以在任何场景下调用,wait必须的同步代码中调用

​ 3.sleep不会释放同步监视器(锁),wait会释放同步监视器(锁)

优点:1. 相比于run方法可以有返回值

​ 2.可以抛出异常

​ 3.支持泛型

操作步骤:

  1. 创建一个实现Callable的实现类
  2. 实现call方法,将操作声明在call方法中
  3. 创建Callable实现类的对象
  4. 将此实现类的对象作为参数,传递到FutureTask构造器,创建FutureTask对象
  5. 将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象


好处:

  1. 提高响应速度
  2. 降低资源消耗
  3. 便于线程管理
  • corePoolSize:核心池的大小
  • maximumPoolSize:最大线程数
  • keepAliveTime:线程没有任务时最多保存多长时间后终止

实现方法:

  1. 提供指定线程数量的线程池
  2. 执行指定的线程操作,需要实现Runnable接口或者Callable接口实现类的对象
  3. 将实例化的对象作为参数 执行service.execute();
  4. 关闭线程池

🎉文章到这里就结束了,感谢诸佬的阅读。🎉

💕欢迎诸佬对文章加以指正,也望诸佬不吝点赞、评论、收藏加关注呀😘
在这里插入图片描述

版权声明


相关文章:

  • java木板小屋教程2024-10-11 08:02:05
  • java基础教程1332024-10-11 08:02:05
  • java扫码教程2024-10-11 08:02:05
  • java教程3122024-10-11 08:02:05
  • java遮罩使用教程2024-10-11 08:02:05
  • java httpclient教程2024-10-11 08:02:05
  • oa开发java教程2024-10-11 08:02:05
  • java转换器教程2024-10-11 08:02:05
  • java基础教程第5讲2024-10-11 08:02:05
  • 零基础Java教程合集2024-10-11 08:02:05