黑马程序员——Java之多线程(2)
来源:互联网 发布:淘宝网点击客服没反应 编辑:程序博客网 时间:2024/06/14 02:05
------Java培训、Android培训、iOS培训、Net培训、期待与您交流! ------
一、多线程的同步
当多个线程操作同一个共享资源时,比如读写同一个变量,存在着资源竞争的问题。为了解决此类问题,需要使用同步机制。这就好比一个人上洗手间,这个人进入洗手间后将门锁上,当他出来时再将锁打开,然后其他让才可以进入。
(1)同步代码块
在Java中提供了同步机制,可以有效地防止资源冲突。同步机制使用synchronizedz关键字。使用同步代码块的目的:阻止两个线程对同一个共享资源进行并发访问。
同步代码块的语法格式:
synchronizedz(obj) { .... //此处的代码就是同步代码块 }
示例:模拟火车站售票系统。
public class ThreadSafeTest implements Runnable{ //设置当前总票数int num = 10;//重写run()方法,定义了线程的执行体public void run() {while (true) {//同步代码块synchronized ("") {if (num>0) {try {//设定线程睡眠的时间//由于线程休眠时可能被中断,所以需要捕获异常Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("车票还有"+num--+"张"); }}}}public static void main(String[] args) {//实例化类对象ThreadSafeTest t = new ThreadSafeTest();//以该类对象分别实例化4个线程Thread tA = new Thread(t);Thread tB = new Thread(t);Thread tC = new Thread(t);Thread tD = new Thread(t);//分别启动线程tA.start();tB.start();tC.start();tD.start(); }}
运行结果:
车票还有10张车票还有9张车票还有8张车票还有7张车票还有6张车票还有5张车票还有4张车票还有3张车票还有2张车票还有1张
(2)同步方法
当某个对象调用了同步方法时,该对象上的其他同步方法必须等待该同步方法执行完毕才能被执行。必须将每个能访问共享资源的方法修饰为synchronized。
同步方法就是在方法前面修饰synchronized关键字的方法,其语法格式如下:
synchronizedz void f() { .... }
示例:
public class ThreadSafeTest implements Runnable{ //设置当前总票数int num = 10;//定义同步方法public synchronized void doit(){if(num>0){try {Thread.sleep(10);} catch (Exception e) {e.printStackTrace();}System.out.println("车票还有"+num--+"张");}}//重写run()方法,在run()方法中调用该同步方法public void run() {while (true) {doit();}}public static void main(String[] args) {//实例化类对象ThreadSafeTest t = new ThreadSafeTest();//以该类对象分别实例化4个线程Thread tA = new Thread(t);Thread tB = new Thread(t);Thread tC = new Thread(t);Thread tD = new Thread(t);//分别启动线程tA.start();tB.start();tC.start();tD.start();}}
运行结果:
车票还有10张车票还有9张车票还有8张车票还有7张车票还有6张车票还有5张车票还有4张车票还有3张车票还有2张车票还有1张
二、线程的通信
在讲诉线程与进程的区别时已经讲解过,线程是共享相同的地址空间,并会协作完成一项任务的,因此线程之间必须能够通信。
Java中提供了wait(),notify()和notifyAll()方法实现了线程间通信机制。这些方法在根类Object中是用final关键字声明的,因此所有的类都包含这些方法。需要说明的是这3个方法仅在synchronized修饰块中才能被调用。
①final void wait() throws InterruptedException方法 :通知当前的线程进入睡眠直到其他线程进入调用notify()唤醒它。在睡眠之前,线程会释放掉所占有的“锁标志”,则其占用的所有synchronized代码块可被别的线程使用。
②final void notify()方法:唤醒在该同步代码块中第一个调用wait()的线程(即第一个进入休眠状态的线程),并且这时会从线程等待池转移到锁标志等待池中,因为该线程没有立刻获取锁标志。
③final void notifyAll()方法:唤醒在该同步代码块中所有调用wait()的线程,并且会从线程等待池中所有该对象的所有线程转移至锁标志等待池中,因为这些线程没有获取锁标。
- 黑马程序员——Java之多线程(2)
- 黑马程序员——Java之多线程
- 黑马程序员——JAVA之多线程
- 黑马程序员—JAVA基础之多线程
- 黑马程序员—java之多线程总结
- 黑马程序员——Java之多线程(1)
- 黑马程序员——Java基础(九)之多线程
- 黑马程序员——Java之多线程(上)
- 黑马程序员——Java之多线程(下)
- 黑马程序员——java基础拾遗之多线程(二) 线程同步、线程通信
- 黑马程序员————JAVA之多线程
- 黑马程序员————Java基础之多线程
- 黑马程序员————Java基础之多线程
- 黑马程序员——java基础之多线程基本概念
- 黑马程序员——java基础之多线程
- 黑马程序员——JAVA基础之多线程的安全问题
- 黑马程序员——Java学习之多线程分析
- 黑马程序员——JAVA笔记之多线程
- OpenGL教程翻译 第十六课 基本的纹理贴图
- Linux操作系统中,*.zip、*.tar、*.tar.gz、*.tar.bz2、*.tar.xz、*.jar、*.7z等格式的压缩与解压
- Hadoop2.7.1安装与配置
- 使用bximage制作软盘映像
- 如何在Qt QML应用中开启cache使得应用更加快捷
- 黑马程序员——Java之多线程(2)
- 实战抓取糗事百科
- VM下ubuntu14.10中搭建android环境(android studio)
- 数据挖掘:基于朴素贝叶斯分类算法的文本分类实践
- Hadoop、Spark、HBase与Redis的适用性讨论
- jQuery选择器总结
- appcompat_v7错误解决方法
- 黑马程序员——Java之IO流(2)
- 常规MOS管与超结MOS管的区别及超结MOS管应用领域介绍