900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 线程实例分析---线程的综合运用(精灵线程 多线程 中断 通信)【java养成】

线程实例分析---线程的综合运用(精灵线程 多线程 中断 通信)【java养成】

时间:2019-06-27 15:36:54

相关推荐

线程实例分析---线程的综合运用(精灵线程 多线程 中断 通信)【java养成】

Java学习打卡:第二十八天

内容导航

Java学习打卡:第二十八天线程实例分析Q1:线程与精灵线程的运用题目内容:问题分析Q2:多线程与interrput的应用题目内容:Q3 模拟买票题目内容题目分析文件File

Java养成计划(打卡第28天)


内容管理: 今天的分享主要是三道线程的题目,之后会再巩固一下File类


线程实例分析

Q1:线程与精灵线程的运用

题目内容:

创建一个包含实例变量i的线程。线程启动之后,首先创建并启动一个精灵线程,然后对变量i循环累加1,直到i的值等于Integer.MAX_VALUE,精灵线程每间隔1s输出一次i的值

问题分析

这个题目非常简单,直接就告诉了run中的内容,那就是要创建一个精灵线程;按照之前的经验我们这里再构造方法中创建就好了,但其实不能这样子做,因为使用构造方法只能创建一个线程,所以看起来比较方便

这里还是直接在run方法中创建第二个线程,只是麻烦一点,使用引用就好了,但是这里只让创建一个精精灵线程,所以使用单一实例模式,创建一个自包含对象,当不空时创建线程

package ThreadDemo;public class ThreadDemo implements Runnable{private static ThreadDemo dem = new ThreadDemo();private int i = 0;Thread t2 = null;@Overridepublic void run() {if(t2 == null)//使用单一实例模式来创建线程对象{t2 = new Thread(dem);//这段代码只能执行一次t2.setDaemon(true);t2.start();}for(;i <= Integer.MAX_VALUE;i++){if(Thread.currentThread().isDaemon()){System.out.println(Thread.currentThread().getName()+"i = " + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}public static void main(String[] args) {Thread t1 = new Thread(dem);t1.start();}}

这里使用了引用,如果不使用引用,必须要有一个对象,上一个消费者中的对象就是Queue的实例q,而构造方法中的this就是指代的对象q,所以执行时就时该对象上锁,这里之前我没有创建一个对象就直接使用,就导致了混乱

输出结果

Thread-1i = 2541

Thread-1i = 521692808

Thread-1i = 1039199618

Thread-1i = 1553714050

Thread-1i = 2086683371

这里输出线程名字是为了检验是否只创建了一个精灵线程

Q2:多线程与interrput的应用

题目内容:

创建t1,t2两个线程,线程t1创建后进入沉睡,睡眠时间为10s,线程2创建后重复产生随机数,直到线程t1终止,每次产生一个随机数后睡眠1s,若产生的随机数小于0.2就向t1放松中断请求,线程t1退出睡眠后,先输出实际睡眠时间,再终止

这里我们也许会倾向于只创建一个类,但是一个类中,多线程或导致混乱,所以这里采用继承的方式创建两个线程,这样才能实现两个线程执行内容不一样,上一个题目是在线程中创建线程所以是一个类

package ThreadDemo;public class Thread1 extends Thread{@Overridepublic void run() {System.out.println("enter t1");//睡眠10s,记录最开始睡眠的时间long primer_time = System.currentTimeMillis();try {Thread.sleep(10*1000);} catch (InterruptedException e) {System.out.println("t1被中断");}//最终睡眠时间long end_time = System.currentTimeMillis();System.out.println("睡眠的实际时间为 :" + (end_time - primer_time)/1000+"s");System.out.println("t1终止");}}

Thread1类就是只用睡眠和记录时间,例外就是被中断

package ThreadDemo;public class Thread2 extends Thread{//要随时向t1发送消息,所以就要包含t1private Thread1 t1;public Thread2(Thread1 t1) {//传入t1this.t1 = t1;}@Overridepublic void run() {System.out.println("enter t2");while(t1.isAlive()){double num = Math.random();System.out.println("t2产生的随机数为:"+ num);if(num < 0.2){t1.interrupt();}try {//每次产生一个数沉睡1sThread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("t2终止");}}

这里由于t2要对t1进行操作,所以t1要作为t2的属性,构造方法中传入t1

最后用起始类启动两个线程

package ThreadDemo;public class ThreadDemo{public static void main(String[] args) {Thread1 t1 = new Thread1();Thread2 t2 = new Thread2(t1);t1.start();t2.start();}}

一种可能的结果是

enter t1

enter t2

t2产生的随机数为:0.7462803496493212

t2产生的随机数为:0.5418461826774316

t2产生的随机数为:0.6781481265082193

t2产生的随机数为:0.7426906269821782

t2产生的随机数为:0.03640488973479594

t1被中断

睡眠的实际时间为 :4s

t1终止

t2终止

Q3 模拟买票

题目内容

模拟3个人买票,张某 李某 赵某买票,售票员只有3张5元的钱,电影票5元1张,张某拿着一张20在李某前面,李某拿着一张10在赵某前面,赵某拿着一张5元的钱

题目分析

这个题目让模拟这个过程,这里线程应该是有3个,对应三个人,和生产者,消费者有点相似

这里售票员单独为类,顾客给钱后执行操作,然后使用一个模拟器进行关联售票员类,不同的顾客给的钱不一样

package ThreadDemo;public class Seller {//持有的钞票的张数private int num5 = 3; //3张5元private int num10 = 0;private int num20 = 0;//售票的方式,给不同的前后执行不同的操作public synchronized void sell(int money){//顾客递交的钱只能时3种情况System.out.println(Thread.currentThread().getName());if(money == 5)//给5元正好(最简单){num5 = num5 +1;System.out.println("钱正好,请拿好你的票");}else if(money == 20){while(!((num10 >= 1&&num5 >= 1)||num5 >= 3)){System.out.println("20,没有零钱,稍等");try {wait();} catch (InterruptedException e) {e.printStackTrace();}}if(num10 >= 1){num10 = num10 -1;num5 = num5 -1;num20 = num20 + 1;System.out.println("你给我20,找你1张10和1张5");}else{num5 = num5-3;num20 = num20 +1;System.out.println("你给我20,找你3张5");}}else if(money == 10) {while(num5 < 1){System.out.println("你给我10,找你的钱不够,请稍等");try {wait();} catch (InterruptedException e) {e.printStackTrace();}}num5 = num5 - 1;num10 = num10 + 1;System.out.println("你给我10元,我找你5元,请拿好");}notifyAll();//这种唤醒的可以不用加具体的前对象System.out.println(Thread.currentThread().getName() +"结束");}}//这里我之前将while的作用域放大,通过加上调试语句找出错误

之后就是一个模拟器,如果将代码直接放入非常麻烦

package ThreadDemo;public class Simulater implements Runnable{private Seller bc;private int money;public Simulater(Seller bc, int money) {this.bc = bc;this.money = money;new Thread(this).start();}@Overridepublic void run() {bc.sell(money);}}

最后使用一个起始类来模拟排队就好了

package ThreadDemo;public class ThreadDemo{public static void main(String[] args) {Seller bc = new Seller();new Simulater(bc,20);new Simulater(bc,10);new Simulater(bc,5);}}

运行之后一种可能的结果为

Thread-0

你给我20,找你3张5

Thread-0结束

Thread-2

钱正好,请拿好你的票

Thread-2结束

Thread-1

你给我10元,我找你5元,请拿好

Thread-1结束

这里也是一种综合运用,关于锁的应用

通过这三道题目就运用了线程基本上大部分的知识,第三个的运用整体上挺简单,但是需要注意的就是创建类的时候的思路,这里我们从题目中可以发现的是售票窗口和三个人,并且有找钱的过程,所以就应该让售票的成为一个类Seller,它的属性就是它所拥有的纸币,方法就售票,而模拟其就是要将人和售票窗口相互连接,使用的线程,每个人都是一个线程,将售票方法放入run中。

文件File

这里单独提到这个类主要是因为之前将IO时漏掉了这个部分,所以现在详细分析一下这个部分。

谈到程序开发,一定时离不开对文件的操作的,比如文件IO,FileOutputStream之类的,在过滤流中最内层一定是介质流,对于文件流就需要创建一个文件的对象。

java如何访问文件属性?

通过Java的API:java.io.File类

如何获取文件对象?

这里是利用File类的构造方法,通过传入文件的路径获取到文件对象

File file = new File("D:\\java\\wb\\Hello.txt"); //这里的路径是以字符串的形式存在

这里需要注意路径中目录是用的双斜杠,而不是单斜杠,而在盘中的路径是单斜杠,这是由于转义字符导致,要是单斜杠,就必须要用转义字符

这里如果文件存在就只是访问,如果不存在就会创建一个文件,File提供了一个方法createNewFile()来判断是否创建了新文件。还有删除文件的方法delete,指定文件是否存在的方法exists,还有打印文件的绝对路径的方法getAbsolutePath(),lenth文件大小(单位是字节),/1024就是kb ,还有很多方法,可以直接在java API中查询

由于文件的内容比较简单,就不继续分享了,之后会再详细分析一下Java中的容器类,比较如何方便操作各种数据结构~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。