导航:首页 > 编程语言 > java程序开发范例

java程序开发范例

发布时间:2025-03-12 01:01:28

‘壹’ java经典编程300例的目录

第1章 Java语言概述 1
实例001 输出“Hello World” 2
实例002 输出控制台传递的参数 2
实例003 输出由“*”组成的三角形 3
实例004 输出符号表情 5
第2章 Eclipse开发工具 6
实例005 下载并运行Eclipse工具 7
实例006 为Eclipse安装汉化包 8
实例007 使用Eclipse注释代码 10
实例008 使用Eclipse格式化代码 11
实例009 安装WindowBuilder插件 12
实例010 开发计算器界面 14
第3章 Java语言基础 15
实例011 输出错误信息与调试信息 16
实例012 从控制台接收输入字符 16
实例013 重定向输出流实现程序日志 17
实例014 自动类型转换与强制类型转换 19
实例015 加密可以这样简单(位运算) 20
实例016 用三元运算符判断奇数和偶数 21
实例017 不用乘法运算符实现2×16 22
实例018 实现两个变量的互换
(不借助第3个变量) 23
第4章 流程控制 25
实例019 判断某一年是否为闰年 26
实例020 验证登录信息的合法性 27
实例021 为新员工分配部门 28
实例022 用switch语句根据消费
金额计算折扣 29
实例023 判断用户输入月份的季节 31
实例024 使用while循环语句与自增
运算符循环遍历数组 33
实例025 使用for循环输出杨辉三角形 34
实例026 使用嵌套循环在控制台上
输出九九乘法表 35
实例027 使用while循环计算1+
1/2!+1/3!…1/20! 36
实例028 使用for循环输出空心的菱形 38
实例029 终止循环体 39
实例030 循环体的过滤器 41
第5章 数组及其常用操作 43
实例031 获取一维数组的最小值 44
实例032 将二维数组中的行列互换 45
实例033 利用数组随机抽取幸运观众 47
实例034 用数组设置JTable表格的
列名与列宽 49
实例035 使用按钮控件数组实现
计算器界面 51
实例036 通过复选框控件数组实现
添加多个复选框控件 52
实例037 使用选择排序法对数组排序 53
实例038 使用冒泡排序法对数组排序 55
实例039 使用快速排序法对数组排序 57
实例040 使用直接插入法对数组排序 59
实例041 使用sort()方法对数组排序 61
实例042 反转数组中元素的顺序 63
第6章 面向对象入门 65
实例043 自定义图书类 66
实例044 温度单位转换工具 67
实例045 成员变量的默认初始化值 68
实例046 单例模式的应用 69
实例047 汉诺塔问题求解 70
实例048 编写同名的方法 71
实例049 构造方法的应用 72
实例050 统计图书的销售量 73
实例051 两只完全相同的宠物 74
实例052 重新计算对象的哈希码 76
实例053 使用字符串输出对象 77
实例054 Java对象的假克隆 78
实例055 Java对象的浅克隆 80
实例056 Java对象的深克隆 82
实例057 序列化与对象克隆 84
实例058 深克隆效率的比较 87
第7章 面向对象进阶 89
实例059 经理与员工的差异 90
实例060 重写父类中的方法 92
实例061 计算几何图形的面积 93
实例062 简单的汽车销售商场 95
实例063 使用Comparable接口自定
义排序 96
实例064 策略模式的简单应用 98
实例065 适配器模式的简单应用 100
实例066 普通内部类的简单应用 102
实例067 局部内部类的简单应用 103
实例068 匿名内部类的简单应用 104
实例069 静态内部类的简单应用 105
实例070 实例化Class类的几种方式 107
实例071 查看类的声明 108
实例072 查看类的成员 110
实例073 查看内部类信息 112
实例074 动态设置类的私有域 113
实例075 动态调用类中方法 115
实例076 动态实例化类 116
实例077 创建长度可变的数组 117
实例078 利用反射重写toString()方法 119
第8章 字符串与包装类 121
实例079 将数字格式化为货币字符串 122
实例080 货币金额大写格式 123
实例081 String类格式化当前日期 125
实例082 字符串大小写转换 126
实例083 字符与Unicode码的转换 128
实例084 判断用户名是否正确 129
实例085 用户名排序 130
实例086 判断网页请求与FTP请求 132
实例087 判断文件类型 133
实例088 判断字符串是否为数字 135
实例089 验证IP地址的有效性 136
实例090 鉴别非法电话号码 137
实例091 将字符串转换成整数 139
实例092 整数进制转换器 140
实例093 获取字符串中汉字的个数 141
实例094 批量替换某一类字符串 142
实例095 查看数字的取值范围 144
实例096 ASCII编码查看器 145
实例097 判断手机号的合法性 146
实例098 用字符串构建器追加字符 147
实例099 去掉字符串中的所有空格 148
实例100 Double类型的比较 149
第9章 Java集合类框架 151
范例101 用动态数组保存学生姓名 152
实例102 用List集合传递学生信息 153
实例103 Map集合二级联动 155
实例104 不重复随机数组排序 157
实例105 for循环遍历ArrayList 159
实例106 Iterator遍历ArrayList 159
实例107 ListIterator逆序遍历ArrayList 160
实例108 制作电子词典 161
实例109 制作手机电话簿 162
第10章 常用数学工具类 164
实例110 角度和弧度的转换 165
实例111 三角函数的使用 166
实例112 反三角函数的使用 167
实例113 双曲函数的使用 168
实例114 指数与对数运算 169
实例115 高精度整数运算 170
实例116 高精度浮点运算 171
实例117 七星彩号码生成器 173
实例118 大乐透号码生成器 174
第11章 错误处理 177
实例119 算数异常 178
实例120 数组下标越界异常 179
实例121 空指针异常 180
实例122 类未发现异常 181
实例123 非法访问异常 182
实例124 文件未发现异常 183
实例125 数据库操作异常 184
实例126 方法中抛出异常 185
实例127 方法上抛出异常 186
实例128 自定义异常类 187
实例129 捕获单个异常 188
实例130 捕获多个异常 189
第12章 输入/输出 191
实例131 显示指定类型的文件 192
实例132 以树结构显示文件路径 193
实例133 查找替换文本文件内容 194
实例134 设置Windows系统的文件
属性 195
实例135 文件批量重命名 196
实例136 快速批量移动文件 197
实例137 删除文件夹中的.tmp文件 198
实例138 将图片文件保存到数据库 199
实例139 从数据库读取图片文件 200
实例140 窗体动态加载磁盘文件 201
实例141 删除文件夹中所有文件 202
实例142 创建磁盘索引文件 208
实例143 控制台记录器 205
实例144 防止创建多个字符串对象 206
实例145 合并多个文本文件 207
实例146 对大文件实现分割处理 208
实例147 将分割后的文件重新合并 209
实例148 读取属性文件单个属性值 210
实例149 向属性文件中添加信息 211
实例150 在复制文件时使用进度条 212
实例151 从XML文件中读取数据 213
实例152 读取Jar文件属性 214
实例153 电子通讯录 215
实例154 批量复制指定扩展名文件 217
实例155 分类保存文件 218
实例156 搜索指定文件夹中的文件 219
实例157 实现文件锁定功能 220
实例158 简单的投票软件 221
实例159 压缩所有文本文件 222
实例160 将压缩包解压到指定文件夹 223
实例161 压缩所有子文件夹 225
实例162 深层文件夹压缩包的释放 226
实例163 解决压缩包中文乱码 227
实例164 Apache实现文件解压缩 228
实例165 把窗体压缩成ZIP文件 229
实例166 解压缩Java对象 230
实例167 文件压缩为RAR文档 231
实例168 解压缩RAR压缩包 233
实例169 为RAR压缩包添加注释 234
实例170 获取压缩包详细文件列表 235
实例171 从RAR压缩包中删除文件 237
实例172 在压缩文件中查找字符串 238
实例173 重命名RAR压缩包中文件 239
实例174 创建自解压RAR压缩包 240
第13章 枚举类型与泛型 242
实例175 查看枚举类型的定义 243
实例176 枚举类型的基本特性 244
实例177 增加枚举元素的信息 245
实例178 选择合适的枚举元素 246
实例179 高效的枚举元素集合 248
实例180 高效的枚举元素映射 249
实例181 使用枚举接口遍历元素 250
实例182 使用泛型实现栈结构 251
实例183 自定义泛型化数组类 253
实例184 泛型方法与数据查询 254
实例185 使用通配符增强泛型 256
实例186 泛型化的折半查找法 257
第14章 Swing入门 259
实例187 从上次关闭位置启动窗体 260
实例188 始终在桌面最顶层显示窗体 261
实例189 设置窗体大小 262
实例190 根据桌面大小调整窗体大小 263
实例191 自定义最大化、最小化和
关闭按钮 265
实例192 禁止改变窗体的大小 267
实例193 指定窗体标题栏图标 267
实例194 设置闪烁的标题栏 269
实例195 实现带背景图片的窗体 270
实例196 背景为渐变色的主界面 271
实例197 随机更换窗体背景 273
实例198 椭圆形窗体界面 275
实例199 钻石形窗体 276
实例200 创建透明窗体 277
实例201 信息提示对话框 278
实例202 设置信息提示对话框的图标 279
实例203 指定打开对话框的文件类型 280
实例204 为保存对话框设置默认文件名 282
实例205 支持图片预览的文件选
择对话框 283
实例206 颜色选择对话框 285
实例207 信息输入对话框 286
实例208 定制信息对话框 287
实例209 拦截事件的玻璃窗格 289
实例210 简单的每日提示信息 290
实例211 震动效果的提示信息 292
实例212 制作圆形布局管理器 293
实例213 制作阶梯布局管理器 295
实例214 密码域控件简单应用 296
实例215 文本域设置背景图片 297
实例216 文本区设置背景图片 298
实例217 简单的字符统计工具 299
实例218 能预览图片的复选框 300
实例219 简单的投票计数软件 301
实例220 单选按钮的简单应用 302
实例221 能显示图片的组合框 303
实例222 使用滑块来选择日期 305
实例223 模仿记事本的菜单栏 308
实例224 自定义纵向的菜单栏 309
实例225 复选框与单选按钮菜单项 311
实例226 包含图片的弹出菜单 312
实例227 工具栏的实现与应用 314
实例228 修改列表项显示方式 315
实例229 列表项与提示信息 316
实例230 表头与列的高度设置 317
实例231 调整表格各列的宽度 319
实例232 设置表格的选择模式 321
实例233 为表头增添提示信息 323
实例234 单元格的粗粒度排序 325
实例235 实现表格的查找功能 326
实例236 应用网格布局设计计算
器窗体 327
第15章 多线程 329
实例237 查看线程的运行状态 330
实例238 查看JVM中的线程名 331
实例239 查看和修改线程优先级 333
实例240 休眠当前线程 335
实例241 终止指定线程 336
实例242 线程的插队运行 337
实例243 使用方法实现线程同步 339
实例244 使用特殊域变量实现线程同步 341
实例245 简单的线程通信 342
实例246 新建有返回值的线程 344
实例247 使用线程池优化多线程编程 346
实例248 哲学家的就餐问题 348
第16章 网络通信 350
实例249 获得内网的所有IP地址 351
实例250 获取网络资源的大小 352
实例251 解析网页中的内容 354
实例252 网络资源的单线程下载 355
实例253 网络资源的多线程下载 357
实例254 下载网络资源的断点续传 359
实例255 建立服务器套接字 362
实例256 建立客户端套接字 363
实例257 设置等待连接的超时时间 364
实例258 获得Socket信息 365
实例259 接收和发送Socket信息 367
实例260 关闭Socket缓冲 369
实例261 使用Socket通信 371
实例262 防止Socket传递汉字乱码 375
实例263 使用Socket传递对象 377
实例264 使用Socket传输图片 379
实例265 使用Socket传输音频 381
实例266 使用Socket传输视频 384
实例267 一个服务器与一个客户端
通信 385
实例268 一个服务器与多个客户端
通信 387
实例269 客户端一对多通信 389
实例270 客户端一对一通信 391
实例271 基于Socket的数据库编程 393
实例272 使用Proxy创建代理服务器 396
实例273 使用ProxySelector选择
代理服务器 397
实例274 聊天室服务器端 399
实例275 聊天室客户端 401
第17章 数据库操作 405
实例276 JDBC连接MySQL数据库 406
实例277 连接SQL Server 2005数据库 407
实例278 JDBC连接Oracle数据库 408
实例279 获取SQL Server指定数据
库中的数据表信息 409
实例280 获取MySQL指定数据库
中的数据表名称 411
实例281 查看数据表结构 412
实例282 动态维护投票数据库 414
实例283 SQL Server数据备份 416
实例284 SQL Server数据恢复 419
实例285 MySQL数据备份 422
实例286 MySQL数据恢复 424
实例287 动态附加数据库 425
实例288 生成SQL数据库脚本 426
实例289 表中字段的描述信息 429
实例290 将员工信息添加到数据表 430
实例291 添加数据时使用数据验证 431
实例292 插入用户登录日志信息 432
实例293 生成有规律的编号 433
实例294 生成无规律的编号 435
实例295 插入数据时过滤危险字符 436
实例296 复选框保存到数据库 437
实例297 把数据复制到另一张表中 438
实例298 批量插入数据 439
实例299 更新指定记录 440
实例300 在删除数据时给出提示信息 442

‘贰’ Java 下面的范例问什么运行不了啊也没有报错。

虽然代码写的不规范,但是没有什么错误啊,我直接拷贝你的代码,然后运行也没有错。

我是这么做的:

1、在桌面上建立一个person.java,把你写的person的代码粘贴进去;

2、同第一步,建立student.java,粘贴student代码;建立test.java,粘贴test代码;

3、依次编译person.java,student.java,test.java

4、运行test,至此结束,程序没有出现任何编译和运行错误,正常打印出了要求打印的信息

‘叁’ 如何在 Java 中正确使用 wait,notify 和 notifyAll

wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。

在 Java 中可以用 wait、notify 和 notifyAll
来实现线程间的通信。。举个例子,如果你的Java程序中有两个线程——即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓
冲区中有内容待消费(不为空)。相应的,消费者可以通知生产者可以开始生成更多的数据,因为当它消耗掉某些数据后缓冲区不再为满。

我们可以利用wait()来让一个线程在某些条件下暂停运行。例如,在生产者消费者模型中,生产者线程在缓冲区为满的时候,消费者在缓冲区为空的时
候,都应该暂停运行。如果某些线程在等待某些条件触发,那当那些条件为真时,你可以用 notify 和 notifyAll
来通知那些等待中的线程重新开始运行。不同之处在于,notify 仅仅通知一个线程,并且我们不知道哪个线程会收到通知,然而 notifyAll
会通知所有等待中的线程。换言之,如果只有一个线程在等待一个信号灯,notify和notifyAll都会通知到这个线程。但如果多个线程在等待这个信
号灯,那么notify只会通知到其中一个,而其它线程并不会收到任何通知,而notifyAll会唤醒所有等待中的线程。

在这篇文章中你将会学到如何使用 wait、notify 和 notifyAll 来实现线程间的通信,从而解决生产者消费者问题。如果你想要更深入地学习Java中的多线程同步问题,我强烈推荐阅读Brian Goetz所着的《Java Concurrency in Practice | Java 并发实践》,不读这本书你的 Java 多线程征程就不完整哦!这是我最向Java开发者推荐的书之一。

如何使用Wait

尽管关于wait和notify的概念很基础,它们也都是Object类的函数,但用它们来写代码却并不简单。如果你在面试中让应聘者来手写代码,
用wait和notify解决生产者消费者问题,我几乎可以肯定他们中的大多数都会无所适从或者犯下一些错误,例如在错误的地方使用
synchronized 关键词,没有对正确的对象使用wait,或者没有遵循规范的代码方法。说实话,这个问题对于不常使用它们的程序员来说确实令人感觉比较头疼。

第一个问题就是,我们怎么在代码里使用wait()呢?因为wait()并不是Thread类下的函数,我们并不能使用
Thread.call()。事实上很多Java程序员都喜欢这么写,因为它们习惯了使用Thread.sleep(),所以他们会试图使用wait()

来达成相同的目的,但很快他们就会发现这并不能顺利解决问题。正确的方法是对在多线程间共享的那个Object来使用wait。在生产者消费者问题中,这
个共享的Object就是那个缓冲区队列。

第二个问题是,既然我们应该在synchronized的函数或是对象里调用wait,那哪个对象应该被synchronized呢?答案是,那个

你希望上锁的对象就应该被synchronized,即那个在多个线程间被共享的对象。在生产者消费者问题中,应该被synchronized的就是那个
缓冲区队列。(我觉得这里是英文原文有问题……本来那个句末就不应该是问号不然不太通……)

永远在循环(loop)里调用 wait 和 notify,不是在 If 语句

现在你知道wait应该永远在被synchronized的背景下和那个被多线程共享的对象上调用,下一个一定要记住的问题就是,你应该永远在
while循环,而不是if语句中调用wait。因为线程是在某些条件下等待的——在我们的例子里,即“如果缓冲区队列是满的话,那么生产者线程应该等
待”,你可能直觉就会写一个if语句。但if语句存在一些微妙的小问题,导致即使条件没被满足,你的线程你也有可能被错误地唤醒。所以如果你不在线程被唤

醒后再次使用while循环检查唤醒条件是否被满足,你的程序就有可能会出错——例如在缓冲区为满的时候生产者继续生成数据,或者缓冲区为空的时候消费者
开始小号数据。所以记住,永远在while循环而不是if语句中使用wait!我会推荐阅读《Effective Java》,这是关于如何正确使用wait和notify的最好的参考资料。

基于以上认知,下面这个是使用wait和notify函数的规范代码模板:
// The standard idiom for calling the wait method in Java synchronized (sharedObject) { while (condition) { sharedObject.wait(); // (Releases lock, and reacquires on wakeup) } // do action based upon condition e.g. take or put into queue }

就像我之前说的一样,在while循环里使用wait的目的,是在线程被唤醒的前后都持续检查条件是否被满足。如果条件并未改变,wait被调用之前notify的唤醒通知就来了,那么这个线程并不能保证被唤醒,有可能会导致死锁问题。

Java wait(), notify(), notifyAll() 范例

下面我们提供一个使用wait和notify的范例程序。在这个程序里,我们使用了上文所述的一些代码规范。我们有两个线程,分别名为
PRODUCER(生产者)和CONSUMER(消费者),他们分别继承了了Procer和Consumer类,而Procer和
Consumer都继承了Thread类。Procer和Consumer想要实现的代码逻辑都在run()函数内。Main线程开始了生产者和消费
者线程,并声明了一个LinkedList作为缓冲区队列(在Java中,LinkedList实现了队列的接口)。生产者在无限循环中持续往
LinkedList里插入随机整数直到LinkedList满。我们在while(queue.size ==
maxSize)循环语句中检查这个条件。请注意到我们在做这个检查条件之前已经在队列对象上使用了synchronized关键词,因而其它线程不能在
我们检查条件时改变这个队列。如果队列满了,那么PRODUCER线程会在CONSUMER线程消耗掉队列里的任意一个整数,并用notify来通知
PRODUCER线程之前持续等待。在我们的例子中,wait和notify都是使用在同一个共享对象上的。
import java.util.LinkedList; import java.util.Queue; import java.util.Random; /** * Simple Java program to demonstrate How to use wait, notify and notifyAll() * method in Java by solving procer consumer problem. * * @author Javin Paul */ public class ProcerConsumerInJava { public static void main(String args[]) { System.out.println("How to use wait and notify method in Java"); System.out.println("Solving Procer Consumper Problem"); Queue<Integer> buffer = new LinkedList<>(); int maxSize = 10; Thread procer = new Procer(buffer, maxSize, "PRODUCER"); Thread consumer = new Consumer(buffer, maxSize, "CONSUMER"); procer.start(); consumer.start(); } } /** * Procer Thread will keep procing values for Consumer * to consumer. It will use wait() method when Queue is full * and use notify() method to send notification to Consumer * Thread. * * @author WINDOWS 8 * */ class Procer extends Thread { private Queue<Integer> queue; private int maxSize; public Procer(Queue<Integer> queue, int maxSize, String name){ super(name); this.queue = queue; this.maxSize = maxSize; } @Override public void run() { while (true) { synchronized (queue) { while (queue.size() == maxSize) { try { System.out .println("Queue is full, " + "Procer thread waiting for " + "consumer to take something from queue"); queue.wait(); } catch (Exception ex) { ex.printStackTrace(); } } Random random = new Random(); int i = random.nextInt(); System.out.println("Procing value : " + i); queue.add(i); queue.notifyAll(); } } } } /** * Consumer Thread will consumer values form shared queue. * It will also use wait() method to wait if queue is * empty. It will also use notify method to send * notification to procer thread after consuming values * from queue. * * @author WINDOWS 8 * */ class Consumer extends Thread { private Queue<Integer> queue; private int maxSize; public Consumer(Queue<Integer> queue, int maxSize, String name){ super(name); this.queue = queue; this.maxSize = maxSize; } @Override public void run() { while (true) { synchronized (queue) { while (queue.isEmpty()) { System.out.println("Queue is empty," + "Consumer thread is waiting" + " for procer thread to put something in queue"); try { queue.wait(); } catch (Exception ex) { ex.printStackTrace(); } } System.out.println("Consuming value : " + queue.remove()); queue.notifyAll(); } } } }

为了更好地理解这个程序,我建议你在debug模式里跑这个程序。一旦你在debug模式下启动程序,它会停止在PRODUCER或者
CONSUMER线程上,取决于哪个线程占据了CPU。因为两个线程都有wait()的条件,它们一定会停止,然后你就可以跑这个程序然后看发生什么了
(很有可能它就会输出我们以上展示的内容)。你也可以使用Eclipse里的Step into和Step over按钮来更好地理解多线程间发生的事情。

本文重点:

1. 你可以使用wait和notify函数来实现线程间通信。你可以用它们来实现多线程(>3)之间的通信。

2. 永远在synchronized的函数或对象里使用wait、notify和notifyAll,不然Java虚拟机会生成 IllegalMonitorStateException。

3. 永远在while循环里而不是if语句下使用wait。这样,循环会在线程睡眠前后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知。

4. 永远在多线程间共享的对象(在生产者消费者模型里即缓冲区队列)上使用wait。

5. 基于前文提及的理由,更倾向用 notifyAll(),而不是 notify()。

这是关于Java里如何使用wait,
notify和notifyAll的所有重点啦。你应该只在你知道自己要做什么的情况下使用这些函数,不然Java里还有很多其它的用来解决同步问题的方

案。例如,如果你想使用生产者消费者模型的话,你也可以使用BlockingQueue,它会帮你处理所有的线程安全问题和流程控制。如果你想要某一个线

程等待另一个线程做出反馈再继续运行,你也可以使用CycliBarrier或者CountDownLatch。如果你只是想保护某一个资源的话,你也可
以使用Semaphore。

‘肆’ 如何在 Java 中正确使用 wait,notify 和 notifyAll

我们先来了解一下为什么要使用wait,notify


首先看一下以下代码:

synchronized(a){
...//1
synchronized(b){
}
}
synchronized(b){
...//2
synchronized(a){
}
}

假设现在有两个线程, t1 线程运行到了//1 的位置,而 t2 线程运行到了//2 的位置,接

下来会发生什么情况呢?

此时, a 对象的锁标记被 t1 线程获得,而 b 对象的锁标记被 t2 线程获得。对于 t1 线程

而言,为了进入对 b 加锁的同步代码块, t1 线程必须获得 b 对象的锁标记。由于 b 对象的锁标记被 t2 线程获得, t1 线程无法获得这个对象的锁标记,因此它会进入 b 对象的锁池,等待 b 对象锁标记的释放。而对于 t2 线程而言,由于要进入对 a 加锁的同步代码块,由于 a 对象的锁标记在 t1 线程手中,因此 t2 线程会进入 a 对象的锁池。

此时, t1 线程在等待 b 对象锁标记的释放,而 t2 线程在等待 a 对象锁标记的释放。由

于两边都无法获得所需的锁标记,因此两个线程都无法运行。这就是“死锁”问题。


在 Java 中,采用了 wait 和 notify 这两个方法,来解决死锁机制。

首先,在 Java 中,每一个对象都有两个方法: wait 和 notify 方法。这两个方法是定义

在 Object 类中的方法。对某个对象调用 wait()方法,表明让线程暂时释放该对象的锁标记。

例如,上面的代码就可以改成:

synchronized(a){
...//1
a.wait();
synchronized(b){
}
}
synchronized(b){
...//2
synchronized(a){
...
a.notify();
}
}

这样的代码改完之后,在//1 后面, t1 线程就会调用 a 对象的 wait 方法。此时, t1 线程

会暂时释放自己拥有的 a 对象的锁标记,而进入另外一个状态:等待状态。

要注意的是,如果要调用一个对象的 wait 方法,前提是线程已经获得这个对象的锁标

记。如果在没有获得对象锁标记的情况下调用 wait 方法,则会产生异常。

由于 a 对象的锁标记被释放,因此, t2 对象可以获得 a 对象的锁标记,从而进入对 a

加锁的同步代码块。在同步代码块的最后,调用 a.notify()方法。这个方法与 wait 方法相对应,是让一个线程从等待状态被唤醒。

那么 t2 线程唤醒 t1 线程之后, t1 线程处于什么状态呢?由于 t1 线程唤醒之后还要在

对 a 加锁的同步代码块中运行,而 t2 线程调用了 notify()方法之后,并没有立刻退出对 a 锁的同步代码块,因此此时 t1 线程并不能马上获得 a 对象的锁标记。因此,此时, t1 线程会在 a 对象的锁池中进行等待,以期待获得 a 对象的锁标记。也就是说,一个线程如果之前调用了 wait 方法,则必须要被另一个线程调用 notify()方法唤醒。唤醒之后,会进入锁池状态。线程状态转换图如下:

classConsumerextendsThread{
privateMyStackms;
publicConsumer(MyStackms){
this.ms=ms;
}
publicvoidrun(){
while(true){
//为了保证push和pop操作的完整性
//必须加synchronized
synchronized(ms){
//如果栈空间已满,则wait()释放ms的锁标记
while(ms.isEmpty()){
try{
ms.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
charch=ms.pop();
System.out.println("Pop"+ch);
ms.notifyAll();
}
//push之后随机休眠一段时间
try{
sleep((int)Math.abs(Math.random()*100));
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
//生产者
classProcerextendsThread{
privateMyStackms;
publicProcer(MyStackms){
this.ms=ms;
}
publicvoidrun(){
while(true){
//为了保证push和pop操作的完整性
//必须加synchronized
synchronized(ms){
//如果栈空间已满,则wait()释放ms的锁标记
while(ms.isFull()){
try{
ms.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
ms.push('A');
System.out.println("pushA");
ms.notifyAll();
}
//push之后随机休眠一段时间
try{
sleep((int)Math.abs(Math.random()*200));
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
//主方法中,启用生产者与消费者两个线程
publicclassTestWaitNotify{
publicstaticvoidmain(String[]args){
MyStackms=newMyStack();
Threadt1=newProcer(ms);
Threadt2=newConsumer(ms);
t1.start();
t2.start();
}
}

部分代码纯手打,望采纳~

‘伍’ java调用python脚本

java调用python脚本是怎样的呢?下面就让我们一起来了解一下吧:
在日常生活中比较常见的java调用python脚本方法有两种,即:
1、通过Jython.jar提供的类库实现。
2、通过Runtime.getRuntime()开启进程来执行脚本文件。
不过第二种方法可能会更好一些,因为Python有时候也是需要用到第三方库的,例如requests,而Python并不支持。因此本地安装Python环境时需要再安装第三方库,然后使用Java调用即可。
参考范例:
Python代码示例:
def hello():
print(Hello,Python)
if __name__ == __main__:
hello()
Java代码示例:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class HelloPython {
public static void main(String[] args) {
String[] arguments = new String[] {python, E://workspace/hello.py};
try {
Process process = Runtime.getRuntime().exec(arguments);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(),
GBK));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
//java代码中的process.waitFor()返回值为0表示调用python脚本成功,
//返回值为1表示调用python脚本失败,这和通常意义上见到的0与1定义正好是相反的
int re = process.waitFor();
System.out.println(re);
} catch (Exception e) {
e.printStackTrace();
}
}
}

‘陆’ Java简历中工作经验怎么写

错误示范:

1、java后台开发

2、前端编写

正确范例:

1、java程序开发岗位,主要负责:代码编写、数据库操作、sql语句优化、wsdl技术调用接口、生成接口等。

2、本身掌握的前端技术加上工作期间积累的html5和css3知识,会同时负责前端的实现。

3、git项目管理,包括:远程git仓库项目的创建与删除等、gitolite中项目操作权限的设置等。

4、研究并使用大数据相关的技术用于解决海量日志的分析,将数据存储到hadoop平台,然后将分析结果导入到Oracle数据库,通过Spring框架将结果进行展示。

阅读全文

与java程序开发范例相关的资料

热点内容
单片机拼搭 浏览:151
程序员没必要穿冲锋衣 浏览:403
nova隐藏app怎么用 浏览:678
单片机程序中ret 浏览:223
爱奇艺上海算法团队 浏览:138
程序员颜值高的人 浏览:362
西数硬件加密和闪迪软件加密 浏览:716
声控足球解压黏土教程 浏览:639
linux下的嵌入式开发 浏览:173
电脑3d加速命令 浏览:105
加密手机号码是怎么回事 浏览:921
女程序员真实图片 浏览:696
pic单片机烧写 浏览:814
linuxping结果 浏览:196
单片机采集负电压 浏览:407
服务器收件什么意思 浏览:893
单片机发数组 浏览:884
魔方虚拟主机销售系统源码 浏览:709
rsa验签php源码 浏览:514
github怎么直接打开源码 浏览:529