java高级(十五)——多线程

创建线程的方式

方式一:继承Thread类

1.创建一个类继承Thread类
2.在子类中重写Thread类的run()方法
3.创建子类对象
4.通过子类对象调用start()方法 (start方法的作用:①启动线程②调用当前线程的run方法)

方式二:实现Runnable接口(建议用这种)

1.创建一个类实现Runnable接口
2.实现类中实现接口的抽象方法
3.创建接口的实现类对象
4.将这个对象作为参数传入Thread类的构造器中,创建Thread类的对象
5.通过Thread类的对象调用start()方法

方式一和方式二两种方式的比较

联系
Thread类底层也是实现的Runnable接口
都需要重写run方法

方式三:实现Callable接口(jdk1.5后新增)相比方式二更加强大

具体步骤:
1.创建一个类实现Callable接口
2.实现Callable接口中的call()方法
3.编写线程具体操作代码
4.创建Callable接口的实现类对象
5.将Callable接口的实现类对象传入FutureTask类的构造器中,
创建FutureTask类的对象
6.将FutureTask类的对象作为参数传入Thread类的构造器中,
创建Thread类的对象,并调用start()方法

相比实现Runnable接口这种方式,实现Callable的方式有什么强大之处?

1.call()方法中可以拥有返回值
2.该方式中可以处理异常
3.该方式中可以使用泛型

方式四:线程池

步骤
		1.创建线程池大小  
					        ExecutorService service = Executors.newFixedThreadPool(10);
		2.执行线程
					// execute       适用于实现Runnable接口
        service.execute(new Runnable() {...}
					// submit      适用于实现Callable接口
        service.submit(new Callable<Object>() {...}
		3.关闭线程池
		service.shutdown();

线程 生命周期

新建
就绪
运行
阻塞
死亡
在这里插入图片描述

线程的同步

线程的安全问题

当一个线程在运行时,遇到了阻塞,这时另一个线程参与了进来,也进行操作,就会造成线程安全问题(如卖票)

如何解决

方式一:同步代码块

synchronize(同步监视器){代码:操作共享数据的代码}

同步监视器(通俗讲就叫锁)

任何一个类的对象,都可以充当锁(要求:多个线程必须共用同一把锁)
也可以使用this代表当前对象,但是只能在创建一个对象的情况下使用(思考)

缺点

操作同步代码块时,只能有一个线程参与,其他线程需要等待,就相当于一个单线程了

方式二:同步方法

在创建方法时使用synchronized

使用实现Runnable接口的方式

只需要创建一个实现类的对象,因此可以直接使用synchronized修饰run()方法
此时,同步监听器为:this

使用继承Thread的方式

因为会创建多个子类的对象,直接使用synchronized修饰run方法不起作用,还需将这个方法使用static关键字修饰
此时,同步监听器就变为:当前类本身

方式三:Lock锁

java.util.concurrent.locks.Lock接口是控制多个线程对共享资源访问的工具。
使用同步锁:创建Lock接口的实现类ReentrantLock的对象
通过对象调用锁定方法lock()/解锁方法unlock()

synchronized与lock锁的异同
相同点

都是解决线程的同步安全问题

区别

synchronized同步方法/代码块的方式,每次执行完代码后自动解锁
而lock锁的方式需要手动锁定、手动解锁

线程的死锁

		不同的线程互相占用了对方的资源不放弃,都在等待对方释放,就形成了线程的死锁(如两个人吃饭,只有一双筷子,都在等待对方将另一只筷子给自己)

解决死锁

		算法、减少同步资源的定义、避免嵌套同步资源

线程的通信

wait()方法

当前线程进去阻塞状态

notify()方法

唤醒被wait的一个线程(如果有多个线程被wait),唤醒优先级较高的

notifyAll()方法

唤醒所有被wait的线程
这3个方法必须放在synchronized代码块中,这三个方法的调用中必须是同步代码块或同步方法的同步监视器

sleep()和wait()方法的区别

相同点
都可以让当前线程进入阻塞状态
不同点

1.声明的位置:

		sleep方法在Thread类中
		wait方法在Object类中

2.调用位置

		sleep方法可以在任何需要的地方调用
		wait方法必须在同步代码块/同步方法中

3.是否释放同步监视器

		sleep方法不释放
		wait方法释放同步监视器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值