🏠个人主页: 黑洞晓威
🧑个人简介:大家好,我是晓威,一名普普通通的大二在校生,希望在CSDN中与大家一起成长。🎁如果你也在正在学习Java,欢迎各位大佬来到我的博客查漏补缺呀,如果有哪里写的不对的地方也欢迎诸佬指正啊。
@[toc]
程序:一段静态的代码进程:运行中的代码
线程:程序的一种执行路径
在java语言中:
线程A和线程B, 和 内存共享。但是 独立,一个线程一个栈。
- 创建一个继承与Thread的子类
- 重写Thread的run()方法
- 创建Thread类子类的对象
- 通过这个对象调用start()
注意:
- t.run() 不会启动线程,只是普通的调用方法而已。不会分配新的分支栈。(这种方式就是单线程。)
- t.start() 方法的作用是:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码任务完成之后,瞬间就结束了。
这段代码的任务只是为了开启一个新的栈空间,只要新的栈空间开出来,start()方法就结束了。线程就启动成功了。启动成功的线程会自动调用run方法,并且run方法在分支栈的栈底部(压栈)。 - run方法在分支栈的栈底部,main方法在主栈的栈底部。run和main是平级的。匿名创建Thread类子类
匿名创建Thread类子类
Thread中的常用方法
- currentThread():静态方法,返回当前代码的线程
- getName():获得当先线程的名字
- setName():设置当前线程的名字
- yield():释放当前cpu的执行权
- join():在线程a中调用线程b的join();则线程a进入阻塞状态,等线程b结束后结束阻塞状态
- sleep(Long militime)让当前线程阻断指定的militime毫秒,此时为阻塞状态
- isAlive();判断线程是否存活
线程的优先级
MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5(默认)
注意:高优先级抢占低优先级线程cpu,但不代表一定先执行完高优先级再执行低优先级
实例:三个窗口卖一百张票
- 创建一个实现了Runnable接口的类
- 重写run();
- 创建实现Runnable类的对象;
- 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象;
通过Thread类的对象调用start();
优势:实现的方式没有类的单继承的局限性
实现的方式更适合处理多个共享数据的类型
- 问题:买票过程中出现了重票错票
- 原因:当某个线程尚未操作完成时,其他线程参与过来,也操作车票
关键字synchronized(同步监视器)
- 操作共享数据的代码就是需要同步的代码
- 同步监视器俗称锁,任何一个类的对象都可以充当锁
- 要求:需要同步的线程要共用同一把锁
- 操作同步代码时只能运行一个线程,相当于一个单线程,但能保证安全问题
实现方法的synchronized
补充:在实现Runnable接口创建多线程的方式中,可以考虑用this充当对象
在继承thread创建多线程的方式中,慎用this充当对象,可以考虑用当前类充当对象
如果操作共享数据的代码在一个方法中
- 实现接口多线程使用同步方法
- 继承thread多线程同步方法需要调用静态方法
public static synchronized void show(){}
总结:
- 同步方法依然涉及到同步监视器,只是不显示说明。
- 非静态同步方法的同步监视器是:this
静态同步方法的同步监视器是:当前类
lock与synchronized的区别
synchronized在执行完同步代码后,自动释放同步监视器。
lock需要手动启动同步(lock),同时结束同步也需要手动实现(unlock)
死锁
练习
银行有一个账户.有两个储户分别向同一个账户存3000元,每次存1000,存三次.每次存完打印账户余额.
例子:使用两个线程交替打印1-100
涉及到的三个方法:
wait():一旦执行此方法,当前线程进入阻塞状态,并释放同步监视器
notify():会唤醒被wait的一个线程,如果有多个线程wait则比较优先级
notifyAll():唤醒所有被wait的线程
注意:
- 上述三个方法必须在同步代码块或同步方法中使用
- 上述方法默认为this.方法,要与synchronized保持一致
不懂的地方:上面代码的wait()与notify()放在循环外无法实现通讯
sleep与wait的异同
相同点:都进入阻塞状态
不同点:1.声明的位置不同:Thread类中声明的sleep,wait在object类中声明
2.调用要求不同:sleep可以在任何场景下调用,wait必须的同步代码中调用
3.sleep不会释放同步监视器(锁),wait会释放同步监视器(锁)
优点:1. 相比于run方法可以有返回值
2.可以抛出异常
3.支持泛型
操作步骤:
- 创建一个实现Callable的实现类
- 实现call方法,将操作声明在call方法中
- 创建Callable实现类的对象
- 将此实现类的对象作为参数,传递到FutureTask构造器,创建FutureTask对象
- 将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象
好处:
- 提高响应速度
- 降低资源消耗
- 便于线程管理
- corePoolSize:核心池的大小
- maximumPoolSize:最大线程数
- keepAliveTime:线程没有任务时最多保存多长时间后终止
实现方法:
- 提供指定线程数量的线程池
- 执行指定的线程操作,需要实现Runnable接口或者Callable接口实现类的对象
- 将实例化的对象作为参数 执行service.execute();
- 关闭线程池
🎉文章到这里就结束了,感谢诸佬的阅读。🎉💕欢迎诸佬对文章加以指正,也望诸佬不吝点赞、评论、收藏加关注呀😘
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/18297.html