Java基础之多线程(三)4月打卡day10
Java基础之多线程(三)4月打卡day10
关于作者
-
作者介绍
🍓 博客主页:
🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。
🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨💻。
1、多线程
要使用多线程必须有一个前提,有一个线程的执行主类。从多线程开始,Java正式进入到应用部分,而对于多线程的开发,从JavaEE上表现的并不是特别多,但是在Android开发之中使用较多,并且需要提醒的是,鄙视面试的过程之中,多线程所问道的问题是最多的。
所谓的同步问题是指多个线程操作统一次元所带来的信息安全性问题,
下面模拟一个简单的卖票程序,要求有3个线程,卖10张票。
package com.day12.demo;
class MyTicket implements Runnable{
private int ticket = 10;
public void run(){
for (int i = 0; i < 20; i++) {
if(ticket > 0){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "买票 =" + this.ticket--);
}
}
}
}
public class TicketDemo {
public static void main(String[] args) {
MyTicket mt = new MyTicket();
new Thread(mt,"票贩子A").start();
new Thread(mt,"票贩子B").start();
new Thread(mt,"票贩子C").start();
}
}
运行上面程序发现,票数为0或者为负数,这种操作我们称为不同步操作。
不同步的唯一好处就是处理速度快(多个线程并发执行),而去银行是一个业务员对应一个客户,这个速度必然很慢。数据的不同步对于访问是不安全的操作。
同步是指所有的线程不是一起进入方法中执行,而是一个一个进来执行。
如果要写实现这把锁的功能,那么可以使用synchronized关键字进行处理,有两种处理模式:同步代码块、同步方法。
同步代码块
如果要使用这种情况必须设置一个要锁定当前对象
package com.day12.demo;
class MyTicket implements Runnable{
private int ticket = 2000;
public void run(){
for (int i = 0; i < 1000; i++) {
//在同一时刻,只允许一个线程进入并且操作,其他线程需要等待
synchronized(this){//线程的逻辑锁
if(ticket > 0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "买票 =" + this.ticket--);
}
}
}
}
}
public class TicketDemo {
public static void main(String[] args) {
MyTicket mt = new MyTicket();
Thread thread1 = new Thread(mt,"票贩子A");
thread1.setPriority(Thread.MIN_PRIORITY);
thread1.start();
new Thread(mt,"票贩子B").start();
new Thread(mt,"票贩子C").start();
}
}
同步方法
package com.day12.demo;
class MyTicket implements Runnable{
private int ticket = 2000;
public void run(){
for (int i = 0; i < 1000; i++) {
//在同一时刻,只允许一个线程进入并且操作,其他线程需要等待
synchronized(this){//线程的逻辑锁
this.sale();
}
}
}
public synchronized void sale(){
if(ticket > 0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "买票 =" + this.ticket--);
}
}
}
public class TicketDemo {
public static void main(String[] args) {
MyTicket mt = new MyTicket();
Thread thread1 = new Thread(mt,"票贩子A");
thread1.setPriority(Thread.MIN_PRIORITY);
thread1.start();
new Thread(mt,"票贩子B").start();
new Thread(mt,"票贩子C").start();
}
}
同步虽然可以保证数据的完整性(线程安全操作),但是其执行的速度很慢。
1.12 死锁
一个线程执行完毕后才可以继续执行,但是如果现在相关的几个线程,彼此几个线程都在等待(同步),那么就会造成死锁。
模拟死锁程序
package com.day12.demo;
class JieFei{
public synchronized void say(Person Person){
System.out.println("给钱放人");
Person.get();
}
public synchronized void get(){
System.out.println("得到钱");
}
}
class Person{
public synchronized void say(JieFei jiefei){
System.out.println("放人就给钱");
jiefei.get();
}
public synchronized void get(){
System.out.println("得到人");
}
}
public class DeadLock implements Runnable {
JieFei jie = new JieFei();
Person person = new Person();
public static void main(String[] args) {
// TODO 自动生成的方法存根
new DeadLock();
}
public DeadLock(){
new Thread(this).start();
jie.say(person);
}
@Override
public void run() {
// TODO 自动生成的方法存根
person.say(jie);
}
}
死锁实在日后多线程程序开发之中经常会遇见问题,而以上的代码并没有任何实际意义,大概可以理解死锁的操作形式就可以了,不用去研究程序。记住一句话:数据要想完整操作必须使用同步,但是过多的同步会造成死锁。
面试题:请问多线程操作统一资源的时候要考虑到那些,会带来的问题?
多线程访问统一资源的时候一定要考虑同步的问题,但是过多的同步会带来死锁。
# 后语
厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。
对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!
- 点赞
- 收藏
- 关注作者
评论(0)