文档库 最新最全的文档下载
当前位置:文档库 › Java基础教案

Java基础教案

Java基础教案

第六章 API常用类

一. Java SE API

应用程序编程接口

二. https://www.wendangku.net/doc/6213445518.html,ng包

运用Java进行编程的基础类,该包中的类由编译器自动导入。

1.主要常用类

(1)Object类

所有Java类的基类,如果在类的声明中未明确使用extends关键字指定父类,则默认为继承自Object类。

toString():返回代表该对象值的字符串。返回字符串格式为:类的全限定名@对象哈希码的十六进制整数值。

问题:什么是对象哈希码?实现原理?

答:是对象在JVM虚拟出来的内存地址,而不是实际物理内存的地址。

equals(Object obj):测试其它某个对象是否与此对象“相等”。Objet类中是通过判断两个对象变量是否指向同一块内存区域。

hashCode():返回该对象的哈希码值。

建议:在自定义类中重写toString()和equals()方法,在重写equals()方法时,建议重写hashCode()方法,因为在某些场合需要比较两个对象是否为相同的对象时,会调用到这两个方法。

问题:重写toString()、equals()、hashCode()方法?

2.基本包装类型

Java对所有的基本类型都提供了对应的包装类,所有基本数据类型都能很方便的和对应的包装类相互转换。

String转成Integer

Integer integer = new Integer(str);

Integer integer = Integer.valueOf(str); //问题:此方式与new运算符的区别? Integer转成String

String str = Integer.toString();

Integer转成int

int i = Integer.intValue();

int转换成Integer

Integer integer = new Integer(i);

Integer integer = Integer.valueOf(i);

String转成int

int i = Integer.parseInt(str);

把int转成String

String str = String.valueOf(i);

String str = i+"";

3.自动装箱、拆箱

装箱:将基本数据类型包装为对应的包装类对象。

拆箱:将包装类对象转换成对应的基本数据类型。

注意:java编译器在编译时期会根据源代码的语法来决定是否进行装箱或拆箱。

4.枚举类型(此部分需要详细学)

枚举类型是指由一组固定的常量组成合法值的类型。

5.数学函数类

https://www.wendangku.net/doc/6213445518.html,ng.Math类是final类,并且它的所有成员变量和成员方法都是静态的。

6.静态导入

在JDK5.0以上版本,使用静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。

import static https://www.wendangku.net/doc/6213445518.html,ng.Math.*;

问题:静态导入的原理?

7.System

System类代表系统,与Math类相似之处,也定义成final的,构造器也定义成了私有的,所有的属性和方法都是static的。

获取标准输入、输出和错误输出流:in/out/err属性

获取当前时间值:

currentTimeMillis():该方法的作用是返回当前的计算机时间,时间的表达格式为当

前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。

实例:计算程序运行需要的时间

long start = System. currentTimeMillis();

for(int i = 0;i < 100000000;i++){

int a = 0;

}

long end = System. currentTimeMillis();

long time = end – start;

nanoTime():

获取或设置属性:getProperties()/getProperty()/setProperty()

获取操作系统的环境变量:getenv(String name)

8.Runtime类(需要学习)

Runtime类提供的方法用于本应用程序与其运行的环境进行信息的交互。这个类采用单例模式构建,即应用程序只能通过它提供的getRuntime()静态方法来获取唯一的实例。

获取运行时的内存情况:maxMemory()/totalMemory()/freeMemory()

gc()方法

https://www.wendangku.net/doc/6213445518.html,ng.System.gc()只是https://www.wendangku.net/doc/6213445518.html,ng.Runtime.getRuntime().gc()的简写,两者的行为没有任何不同。

System.gc()写起来比Runtime.getRuntime().gc()简单点. 其实基本没什么机会用得到这个命令, 因为这个命令只是建议JVM安排GC运行, 还有可能完全被拒绝。 GC本身是会周期性的自动运行的,由JVM决定运行的时机,而且现在的版本有多种更智能的模式可以选择,还会根据运行的机器自动去做选择,就算真的有性能上的需求,也应该去对GC的运行机制进行微调,而不是通过使用这个命令来实现性能的优化。

9.字符串String类

String代表不可变的字符序列。是final类。

创建字符串对象的方式(分析内存)

String a = "hello";

String b = new String("hello");

使用"+"拼接字符串

String str = "你好"+"世界";

"+"也能将字符串与其它的数据类型相连接形成一个新的字符串。

String a = "abc"+12

字符串长度

String类中有length()方法可以获得此字符串的长度(注意与数组length属性区分开)。

字符串比较

“=”用来比较两个字符串是否存储在同一内存位置。

equals方法用来比较两个字符串的内容是否相等。

常用方法

比较两个字符串,忽略大小写形式

boolean equalsIgnoreCase(String val)

按字典顺序比较两个字符串,如果两个字符串相等,则返回0,如果字符串在参数值之前,则返回值小于0,如果字符串在参数值之后,则返回值大于0。

int compareTo(String val)

按字典顺序比较两个字符串,不考虑大小写

int compareToIgnoreCase(String val)

检查一个字符串是否以参数字符串开始

boolean startsWith(String val)

检查一个字符串是否以参数字符串结束

boolean endsWith(String val)

返回指定字符ch在此字符串中第一次出现处的索引值;如果未出现该字符,则返回-1。

int indexOf(int ch)

返回第一次出现的指定子字符串str在此字符串中的索引值;如果未出现该字符串,则返回-1.

int indexOf(String str)

返回最后一次出现的指定字符在此字符串中的索引值;如果未出现该字符,则返回-1.

int lastIndexOf(int ch)

返回最后一次出现的指定子字符串str在此字符串中的索引值;如果未出现该字符串,则返回-1。

int lastIndexOf(String str)

从指定索引index处提取单个字符,索引中的值必须为非负

char charAt(int index)

提取从位置索引index开始直到此字符串末尾的这部分子字符串

String substring(int index)

提取从 beginindex开始直到 endindex(不包括此位置)之间的这部分字符串

String substring(int beginIndex, int endIndex)

将指定字符str串联接到此字符串的结尾成为一个新字符串返回。

String concat(String str)

返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 而生成的。

String replace(char oc, char nc)

使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串

String replace(CharSequence target, CharSequence replacement) 返回字符串的副本,忽略前导空白和尾部空白

String trim()

将此字符串中的所有字符都转换为大写

String toUpperCase();

将此字符串中的所有字符都转换为小写

String toLowerCase();

String类的静态方法可以将基本类型数据、Object类型转换为字符串。

static String valueOf()

练习:

1.检测电子邮件地址是否有效

2.编写一个java方法,用来统计所给字符串中大写英文字母的个数,小写英文字母的个数以及非英文字母的个数。

10.StringBuilder/StringBuffer类

StringBuilder/StringBuffer代表可变的字符序列。

StringBuilder类的方法不保证线程同步,在非线程的情况下使用会有较好的效率。 StringBuffer类的方法保证线程同步。

构造对象

new StringBuilder();//构造一个不到字符的字符串缓冲区,初始容量为16个字符。 new StringBuilder(String str);//构造一个字符串缓冲区,并将其内容初始化为指定字符串内容

常用方法

将指定的字符串追加到此字符序列

StringBuilder append(String str);

将字符串str插入此字符序列指定位置中

StringBuilder insert(int offset, String str)

确定StringBuffer对象的长度

int length( )

使用 ch 指定的新值设置 pos 指定的位置上的字符

void setCharAt(int pos, char ch)

转换为字符串形式

String toString( )

反转字符串

StringBuilder reverse()

此方法将删除调用对象中从 start 位置开始直到 end 指定的索引–1 位置的字符序列

StringBuilder delete(int start, int end)

此方法将删除 pos 指定的索引处的字符

StringBuilder deleteCharAt(int pos)

此方法使用一组字符替换另一组字符。将用替换字符串从 start 指定的位置开始替换,直到 end 指定的位置结束

StringBuilder replace(int start, int end, String s)

11.正则表达式

假设搜索一个包含字符“cat”的字符串,搜索用的正则表达式就是“cat”。如果

搜索对大小写不敏感,单词“catalog”、“Catherine”、“sophisticated”都可以匹配。

(1)句点符号

假设想要找出三个字母的单词,而且这些单词必须以“t”字母开头,以“n”字母结束。另外,假设有一本英文字典,你可以用正则表达式搜索它的全部内容。要构造出这个正则表达式,你可以使用一个通配符——句点符号“.”。

正则表达式:t.n

匹配:tan,Ten,ton,t n,t#n等

(2)方括号符号

为了解决句点符号匹配范围过于广泛这一问题,你可以在方括号(“[]”)里面指定看来有意义的字符。

正则表达式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”。但“Toon”不匹配,因为在方括号之内你只能匹配单个字符。

正则表达式:t[aeio]n

匹配:tan,tin,ton

(3)或符号

“|”操作符的基本意义就是“或”运算。要匹配“toon”,使用“t(a|e|i|o|oo)n”正则表达式;这里必须使用圆括号“()”。

正则表达式:t(e|i|o|oo)n

匹配:ten,Ten,tin,ton,toon

(4)表示匹配次数的符号

*:0次或者多次

+:1次或者多次

?:0次或者1次

{n}:恰好n次

{n,m}:从n次到m次

匹配电话号码

0[1-9]{2}\-[1-9]{1}[0-9]{7}

如果不希望出现“-”符号

例:022********

0[1-9]{2}\-?[1-9]{1}[0-9]{7}

注意:可选范围还可以为[a-z] [A-Z]

(5)"否"符号

“^”符号称为“否”符号。如果用在方括号内,“^”表示不想要匹配的字符。

(6)圆括号和空白符号

\S:匹配空格

():代表分组

(7)其它符号

\d:[0-9]

\D:[^0-9]

\w:[A-Za-z0-9]

\W:[^A-Za-z0-9]

(8)起始/结束

^:起始

$:结束

(9)常用功能

字符串匹配

String str1 = "javaSEjaeaEEjasaME";

Pattern p1 = https://www.wendangku.net/doc/6213445518.html,pile("^j.*E$");

Matcher m1 = p1.matcher(str1);

boolean result1 = m1.matches();

System.out.println(result1);

Pattern p2 = https://www.wendangku.net/doc/6213445518.html,pile("j..a");

Matcher m2 = p2.matcher(str1);

boolean result2 = m2.find();

System.out.println(result2);

字符串分割

String str2 = "java,android,javaee,sqlserver,oracle";

Pattern p3 = https://www.wendangku.net/doc/6213445518.html,pile(",");

String[] arr = p3.split(str2);

for(String str:arr){

System.out.println(str);

}

字符串替换

String str3 = "delete from emp where empno=7744";

Pattern p4 = https://www.wendangku.net/doc/6213445518.html,pile("delete|insert|update");

Matcher m3 = p4.matcher(str3);

String s = m3.replaceAll("").trim();

System.out.println(s);

字符串查找

String str4 = "javaSEandroidjavaEEsqlserveroracle";

Pattern p5 = https://www.wendangku.net/doc/6213445518.html,pile("java(.){2}");

Matcher m4 = p5.matcher(str4);

while(m4.find()){

System.out.println(m4.group());

}

三.java.util包

1.java.util.Random类

此类用于生成随机数

构造方法

Random();创建一个新的随机数生成器(使用当前时间毫秒值作为种子)

Random(long seed);使用单个long种子创建一个新随机数生成器。//看其含义注意:如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列

具体方法:

返回一个0到n(不包括n)的随机整数值

nextInt(int n);

nextInt();

nextFloat();

返回在 0.0 和 1.0 之间均匀分布的 double 值

nextDouble();

nextBoolean();

2.Arrays类

Arrays类提供了用来操作数组的各种静态方法,被称为数组操作工具类。

返回数组内容的字符串表示形式

static String toString(int[] a);

使用快速排序法对指定的int型数组按数字升序进行排序

static int[] sort(int[] a);//快速排序法原理

使用二分搜索法搜索指定的int型数组,获得指定值所在的索引值

static int binarySearch(int[] a, int key); //二分搜索法搜索

复制指定的数组

static int[] copyOf(int[] original, int newLength);

3.java.util.Date类

世界时间标准的概念(UTC、GMT)

java.util.Date类表示特定的时间,精确到毫秒。

构造方法

Date():使用系统当前的时间创建一个Date实例;内部就是使用System.currentTimeMillis()获取系统当前时间的毫秒数来创建Date对象

Date(long dt):使用自1970年1月1日00:00:00 GMT以来的指定毫秒数创建一个Date 实例。

常用方法

getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。

toString() 把此 Date 对象转换为以下形式的 String dow mon dd hh:mm:ss zzz yyyy :星期月日时:分:秒时区年

4.java.util.Calendar类

Calendar类(日历)是一个抽象基类,主要用于完成日历字段之间相互操作的功能。即可以设置和获取日历数据的特定部分。

获取Calendar类的实例

Calendar.getInstance();

调用它的子类GregorianCalendar的构造方法

获取指定日历字段值

public int get(int field)

更改指定日历字段值

void set(int field, int value) //不会重新计算日历的时间值

void add(int field, int amount) //强迫日历系统立即重新计算日历的毫秒数和所有字段

四.国际化和格式化

1.国际化(I18N):是指某个软件应用程序运行时,在不改变它们程序逻辑的前提下支持各种语言和区域。

2.本地化(简称L10N):是指某个软件应用程序在运行时,能支持特定地区。

3.格式化是指对一些语言和区域敏感的数据按照特定的要求进行特定输出。

4.国际化相关类

java.util.Locale类:代表特定的地理、政治和文化地区

国际标准语言代码是小写的两个字母。中文zh、英文en

区域代码是大写的两个字母。大陆CN、台湾TW、美国US

java.util.ResourceBundle类:用于加载一个资源包

static ResourceBundle getBundle(String baseName, Locale lo)

String getString(String key)

java.text.MessageFormat类:提供了与语言无关的生成连接消息的方式。

public static String format(String pattern, Object... args)

pattern用来指定消息模式串,可用"{索引}"来预设占位符。

args是为消息模式中的指定位符传值

classpath下的资源文件

msgs.properties

msgs_zh_CN.properties

通过native2ascii.exe把本地字符转换成Unicode码

Locale locale = https://www.wendangku.net/doc/6213445518.html,;

ResourceBundle bundle = ResourceBundle.getBundle("language", locale);

String title = bundle.getObject("title").toString();

String author = bundle.getObject("author").toString();

System.out.println(title);

System.out.println(author);

5.java.text.DateFormat类

DateFormat用来格式化(日期->文本)、解析(文本->日期)日期/时间。

6.java.text.NumberFormat 类

NumberFormat类用来格式化和解析数值。

7.大数字操作

Java语言支持大数字的操作。在java.math包中提供了两个专门的类:BigInteger 和BigDecimal类。

第七章多线程

一. 线程概述

各个程序看起来是在同一时间内执行多个任务。每个任务通常称之为一个线程。这种能同时执行多个线程的程序称之为多线程程序。

二. 进程和线程的区别

1. 进程

进程是指每个独立程序在计算机上的一次执行活动。

2. 线程

线程就是一个程序内部的一条执行路径。如果一个程序中可以在同一时间内执行多个线程,就说这个程序是支持多线程的。

3. 线程和进程的区别

在操作系统中同时运行多个程序叫多进程,在同一应用程序中,多条执行路径并发执行叫多线程。

●每个进程有独立的代码和数据空间,进程间的切换开销大。

●同一进程内的多个线程共享相同的代码和数据空间,每个线程有独立的运行栈和程

序计数器,线程间的切换开销小。

三. 多线程应用

●程序需要同时执行两个或多个任务。

●程序需要实现一些需要等待上一个任务完成时才能继续下一个任务的执行,如用户输

入、文件读写操作、网络操作、搜索等。

●需要一些后台运行的程序时。

四. 创建和启动线程

1. 创建新线程

(1)继承Thread类重写run()方法

class MyThread extends Thread{

public void run(){

……

}

}

Thread thread2 = new MyThread();

(2)实现Runnable接口,实现run()方法。

class MyRunner implements Runnable{

public void run(){

……

}

}

Thread thread1 = new Thread(new MyRunner());

2.启动线程

thread1.start();

thread2.start();

3.线程运行原理分析

主线程先执行,然后启动子线程,新线程并不会立刻得到执行,而是统一由JVM根据时间片来调度,调度到哪个线程就由哪个线程执行片刻。多次运行,每次的输出结果都不可能相同,说明JVM调度线程的执行顺序是随机的。

JVM划分时间片间隔的机制是依托于操作系统的时间片调度机制。

Windows操作系统:基于优先级的抢占式线程调度。

Linux操作系统:抢占式内核和实时机制。

五. 线程的生命周期

1. 新线程

当创建Thread类实例时,此实例则处于“新建”状态。当一个线程处于新建状态时,它的线程体中的代码并未得到JVM的执行。

2. 可运行的线程

当一个线程被阻塞或处于等待状态时,它暂时处于停止,不会执行线程体内的代码。

3. 被阻塞和等待状态下的线程

阻塞、等待、超时

示例:

模拟下载文件(TextWaitAndNotify.java)

示例

public class DownLoadDemo {

private class DownLoadFile extends Thread{

String[] fileName = {"Java基础与案例详解","JavaEE整合开发","Oracle11g 权威指南","Android内核剖析","Android移动开发技术","JQuery权威指南"};

boolean flag = false;

@Override

public void run() {

try{

Thread.sleep(3000);

}

catch(InterruptedException ex){

ex.printStackTrace();

}

download();

}

public synchronized void download(){

DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

for(int i=0;i

int rnd = new Random().nextInt(10);

int rnd_n = (rnd>0?rnd:1)+5;

//System.out.println("随机数:"+rnd);

if(rnd>5){

try{

System.out.println("["+format.format(new

Date())+"]["+Thread.currentThread().getName()+"]"+fileName[i]+"网络超时");

wait(6000);

}

catch(InterruptedException ex){

ex.printStackTrace();

}

}

else{

try{

System.out.println("["+format.format(new

Date())+"]["+Thread.currentThread().getName()+"]"+fileName[i]+"文件下载用时:"+rnd+"毫秒");

notifyAll();

}

catch(Exception ex){

ex.printStackTrace();

}

}

}

}

}

public static void main(String[] args) {

DownLoadDemo demo = new DownLoadDemo();

demo.new DownLoadFile().start();

demo.new DownLoadFile().start();

}

}

4.被终止的线程

run()方法执行完毕自然终止。

未捕获到的异常事件终止了run()方法。

六. 线程睡眠

在线程体中调用sleep()方法会使当前线程进入睡眠状态,调用sleep()方法时需要传入一个毫秒数作为当前线程睡眠的时间,线程睡眠相应的时间后便会苏醒,重新进入可运行状态。

线程睡眠并不会让线程释放它所持有的同步锁,而且在这期间也不会阻碍其他线程的运行。Threed.sleep(100);

线程唤醒可以将沉睡或阻塞的线程唤醒。线程唤醒可以使执行了sleep操作的线程或执行了wait操作或者join操作的线程唤醒。线程沉睡要指定沉睡的时间,如果对该线程执行interrupt操作,线程可以提早继续运行。

示例:

谁唤醒了我(TextSleepAndInterrupt.java)

七. 线程让步

Threed.yield()方法让当前运行的线程放弃其所占用的CPU时间片,以便让其他线程运行,用线程让步的目的是让线程能适当地轮转,但并不能保证达到此效果。因为即使当前线程放弃时间片,还有可能再次被Java虚拟机(JVM)选中。

yield只是让出cpu的占有权,但是当前线程仍处在可执行状态,调用yield后会先检测是否有相同优先级的处于可执行状态,如果有则把cpu的执行权交给此线程,否则继续运行当前线程,也就是说yield只是让同等优先级的线程有执行的机会,调用yield后当前线程可能不受影响继续运行。

public class TextThreadYield {// 操作线程让步的类

private Vector vector = new Vector();// 创建向量集合

private DateFormat dateFormat = new SimpleDateFormat("HH-mm-ss:SSSS");// 创建日期格式

private boolean isFlag = false;

private class Yield extends Thread {//让步接收文件类

public Yield() {

this.setName("接收文件");//设置线程名称

this.setDaemon(true);// 如果SendFile线程结束,则该线程自动结束}

public void run() {

while (!isFlag) {// 标识为真进行循环

try {

Thread.sleep(100);// 休眠

} catch (InterruptedException e) {//捕获唤醒异常

System.out.println("唤醒异常:"+e.getMessage());

}

if (vector.size() == 0) {//判断向量集合大小

System.out.println(dateFormat.format(new Date())+ "\t向量集合中没有文件,执行yield操作");

Thread.yield();//调用线程让步

} else {

String ss = (String) vector.remove(0);//移队文件获得对象

System.out.println(dateFormat.format(new Date())+"\t取到文件,名为" + ss);

}

}

}

}

private class SendFile extends Thread {//发送文件类

private String[] files = new String[] { "新闻文件", "国内旅游向导", "山水名画欣赏", "发家致富说明" };

public SendFile() {

this.setName("发送文件");

}

public void run() {

try {

for (int i = 0; i < files.length; i++) {//循环使线程休眠

Thread.sleep(201);//线程休眠

vector.add(files[i]);//添加文件

}

Thread.sleep(100);//线程休眠

} catch (InterruptedException e) {//捕获唤醒异常

System.out.println("唤醒异常:"+e.getMessage());

}

}

}

public static void main(String []args){//java程序主入口处

TextThreadYield text=new TextThreadYield();//实例化对象

text.new Yield().start();//实例对象启动线程

text.new SendFile().start();

}

}

八. 线程的加入

有时需要线程间的接力来完成某项任务,即线程需要等待其他线程运行结束后才能够开始,否则继续等待。

这就需要调用线程类的join()方法,join()方法可以使两个交叉执行的线程变成顺序执行。

示例:

有始有终(TextThreadJoin.java)

九. 守护线程

Java虚拟机的垃圾回收线程可以称为守护线程。守护线程是一种特殊的线程,它是否运行结束并不仅仅依赖于自己run()方法内的程序,还依赖于其他非守护线程。

普通线程可以通过Thread类的setDaemon方法设置为守护线程,参数为true时表示该线程为守护线程。任何线程都可以通过Thread类的isDaemon()方法判断是否为守护线程。

线程被运行后,Thread类的setDaemon方法无效,即必须在调用方法start()之前调用setDaemon方法,才能设置该线程为守护线程。

如果所有的非守护线程运行结束,无论守护线程有没有运行结束,都将不再运行。如果一个程序没有任何守护线程,则所有非守护线程运行结束后就退出。程序中启动的线程默认为非守护线程,但在守护线程中启动的线程都是守护线程。

示例:

爱子(TextThreadDaemon.java)

十. 线程的调度和优先级

线程的调度是让JVM对多个线程进行系统级的协调,以避免因多个线程争用有限的资源

而导致应用系统死机或者崩溃。

每个线程都有一个“优先级”,优先级可以用整数表示,取值范围为0~10,0为最低优先级,10为最高优先级;当决定哪个线程需要调度时,首先查看是否存在优先级高的可调度线程,如果存在,就从中选择进行调度。当该线程的时间片到达之后,系统查看是否存在另一个优先级为比较高的可调度线程;如果存在就调度。这样依次进行判断调度线程。

示例:家族等级(TextPriorityLevel.java)

Thread t1 = new Thread(…);

t1.setPriority(Thread.MAX_PRIORITY);

//t1.getPriority();//获取当前线程的优先级

//t1.setPriority(Thread.MIN_PRIORITY);

//t1.setPriority(Thread.NORMAL_PRIORITY);

//t1.setPriority(6);//1~10

十一. Thread类介绍

Public void start():启动该线程。

Public static Thread currentThread():返回对当前正在执行的线程对象的引用。Public final Boolean isAlive():测试线程是否还活着。

Public Thread.State getState():返回该线程的当前状态。

Public final String getName():返回该线程的名称。

Public final void setName(String name):设置该线程的名称。

Public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。Public final void setPriority(int newPriority):更改线程的优先级。

Public static void sleep(long millis):在指定的毫秒数内让当前正在执行的线程休眠。Public void interrupt():中断线程。

十二. 线程同步

大多数需要运行多线程的应用程序中,两个或多个线程需要共享对同一个数据的访问。如果每个线程都会调用一个修改该数据状态的方法,那么这些线程将会互相影响对方的运行。为了避免多个线程同时访问一个共享数据,必须使用访问同步。

例:在不进行任何线程同步处理的情况下,开发世界杯球票销售系统。

注意:JVM在执行多线程程序是的运行原理。

相关文档
相关文档 最新文档