西北农林科技大学java多线程实验报告.docx
《西北农林科技大学java多线程实验报告.docx》由会员分享,可在线阅读,更多相关《西北农林科技大学java多线程实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
![西北农林科技大学java多线程实验报告.docx](https://file1.bdocx.com/fileroot1/2022-11/30/3f73ac24-896f-49a5-93fb-11db3309438e/3f73ac24-896f-49a5-93fb-11db3309438e1.gif)
西北农林科技大学java多线程实验报告
实验7多线程
1.实验目的
(1)掌握Java多线程的概念和实现方法
(2)掌握Java多线程的同步问题
2.实验内容
任务一:
火车售票
假设有火车票1000张,创建10个线程模拟10个售票点,每个售票点100毫秒买一张票。
打印出售票过程,注意使用synchronized确保同一张票只能卖出一次。
程序运行结果见左图。
打开Eclipse
Tickets.java
publicclassTicketextendsThread{
intticket=1000;
Stringname="";
publicvoidrun(){
while(true){
synchronized(name){
if(ticket<=0){
break;
}
else{
System.out.println("第"+Thread.currentThread().getName()+"售票点卖出了第"+ticket--+"张票");
}
try{
Thread.sleep(100);
}
catch(InterruptedExceptione){
}
}
}
}
}
Test.java
publicclassTest{
publicstaticvoidmain(Stringargs[]){
Tickett=newTicket();
newThread(t,"1").start();
newThread(t,"2").start();
newThread(t,"3").start();
newThread(t,"4").start();
newThread(t,"5").start();
newThread(t,"6").start();
newThread(t,"7").start();
newThread(t,"8").start();
newThread(t,"9").start();
newThread(t,"10").start();
}
}
任务二:
银行存款
假设某家银行,它可接受顾客的汇款,每做一次汇款,便可计算出汇款的总额。
现有两个顾客,每人都分3次,每次100元将钱到入。
试编写一个程序,模拟实际作业。
程序如下:
classCBank
{privatestaticintsum=0;
publicstaticvoidadd(intn){
inttmp=sum;
tmp=tmp+n;//累加汇款总额
try{
Thread.sleep((int)(10000*Math.random()));//小睡几秒钟
}
catch(InterruptedExceptione){}
sum=tmp;
System.out.println("sum="+sum);
}
}
classCCustomerextendsThread//CCustomer类,继承自Thread类
{publicvoidrun(){//run()method
for(inti=1;i<=3;i++)
CBank.add(100);//将100元分三次汇入
}
}
publicclassEx7_1
{publicstaticvoidmain(Stringargs[])
{CCustomerc1=newCCustomer();
CCustomerc2=newCCustomer();
c1.start();c2.start();
}
}
[基本要求]运行程序5次,观察每次运行结果是否相同。
[思考问题]运行结果每次是否相同,运行时间是否相同,为什么?
①要使程序运行结果每次相同,应该怎样修改程序?
②程序中为什么要使用异常处理?
答:
运行程序5次,观察每次运行结果不相同:
运行结果每次是否相同,运行时间不相同,因为程序不同步。
①为了使程序运行结果每次相同,程序修改如下:
CBank.java
classCBank
{privatestaticintsum=0;
publicsynchronizedstaticvoidadd(intn){
inttmp=sum;
tmp=tmp+n;//累加汇款总额
try{
Thread.sleep((int)(10000*Math.random()));//小睡几秒钟
}
catch(InterruptedExceptione){}
sum=tmp;
System.out.println("sum="+sum);
}
}
CCustomer.java
classCCustomerextendsThread//CCustomer类,继承自Thread类
{publicvoidrun(){//run()method
for(inti=1;i<=3;i++)
CBank.add(100);//将100元分三次汇入
}
}
Ex7_1.java
publicclassEx7_1
{publicstaticvoidmain(Stringargs[])
{CCustomerc1=newCCustomer();
CCustomerc2=newCCustomer();
c1.start();
c2.start();
}
}
运行结果如下:
②程序中为什么要使用异常处理?
程序执行时经常会出现除零溢出、数组越界等运行错误,影响程序的正常执行。
Java语言通过面向对象的异常处理机制来解决运行期间的错误,可以预防错误的程序代码或系统错误所造成的不可预期的结果发生。
减少编程人员的工作,增加了程序的灵活性,增加程序的可读性和健壮性.
任务三:
生产者和消费者问题
生产者生产面包,消费者消费面包,“生产”和“消费”各代表一个进程,当生产者没有生产出面包的时候,消费者不能消费面包。
当消费者没有消费完面包的时候,生产者不能再生产。
程序效果如下:
程序要求:
一次生产5个面包,一次消费5个面包。
注同步机制,wait()方法,notify()方法的使用。
启动Eclipse:
程序代码如下:
Bread.java
publicclassBreadimplementsRunnable{
intsum=0;
Bread(intn){sum=n;}
voidpro(){
while(sum<5){
sum=sum+1;
System.out.println(sum+"个");
}
System.out.println("生产完毕。
");
System.out.println("开始消费--");
notifyAll();
}
voidcon(){
if(sum<5){
System.out.println("还没有生产出面包,等待中--");
try{
wait();
}
catch(InterruptedExceptione){}
}
for(inti=0;i<5;i++){
System.out.println(sum+"个");
sum=sum+(-1);
}
System.out.println("消费完毕。
");
}
publicsynchronizedvoidbread(intk){
if(k==1){
pro();
}
if(k==-1){
con();
}
}
publicvoidrun(){
if(Thread.currentThread().getName().equals("produce")){
System.out.println("启动消费");
bread(-1);
}
if(Thread.currentThread().getName().equals("consume")){
System.out.println("开始生产--");
bread
(1);
}
}
}
Wt.java
publicclassWt{
publicstaticvoidmain(Stringargs[]){
Breadbread=newBread(0);
Threadthread1=newThread(bread);
Threadthread2=newThread(bread);
thread1.setName("produce");
thread2.setName("consume");
thread1.start();
thread2.start();
}
}
运行结果如下:
实验8
1.实验目的
(1)掌握Socket通信
(2)掌握UDP通信
2.实验内容
任务一:
InetAddress类练习
使用InetAddress类的方法获取的主机的IP地址;获取本地机的名称和IP地址。
程序运行结果如图所示:
程序代码如下:
import.*;
publicclassWt{
publicstaticvoidmain(Stringargs[]){
try{
InetAddressaddress_1=InetAddress.getByName("");
System.out.println("学校的IP地址:
"+address_1.getHostAddress());
InetAddressaddress_2=InetAddress.getLocalHost();
System.out.println("本机的IP地址:
"+address_2.getHostAddress());
System.out.println("本机的名称"+address_2.getHostName());
}
catch(UnknownHostExceptione){
System.out.println(e);
}
}
}
运行结果如下:
任务二:
Socket类和ServerSocket类练习
利用Socket类和ServerSocket类编写一个C/S程序,实现C/S通信。
客户端向服务器端发送“Time”命令,服务器端接受到该字符串后将服务器端当前时间返回给客户端;客户端向服务器端发送“Exit”命令,服务器端向客户端返回“Bye”后退出。
基本要求:
编写完整程序;两人一组,一个作为服务器端,另一人作为客户端。
服务器端和客户端都需要打印出接受到的消息和发出的命令。
程序运行结果如下:
客户端服务器端
Client.java
importjava.io.*;
import.*;
publicclassClient{
publicstaticvoidmain(Stringargs[])
{
Socketmysocket;
DataInputStreamin=null;
DataOutputStreamout=null;
try{
mysocket=newSocket("127.0.0.1",4331);
in=newDataInputStream(mysocket.getInputStream());
out=newDataOutputStream(mysocket.getOutputStream());
Strings1="Time";
out.writeUTF(s1);
Thread.sleep(500);
Strings=in.readUTF();//in读取信息,堵塞状态
System.out.println("客户收到:
"+s);
out.writeUTF("exit");
Thread.sleep(500);
Strings2=in.readUTF();//in读取信息,堵塞状态
System.out.println("客户收到:
"+s2);
return;
}
catch(Exceptione){
System.out.println("服务器已断开"+e);
}
}
}
Server.java
importjava.io.*;
importjava.util.*;
import.*;
importjava.text.SimpleDateFormat;
publicclassServer{
publicstaticvoidmain(Stringargs[]){
ServerSocketserver=null;
Socketyou=null;
DataOutputStreamout=null;
DataInputStreamin=null;
try{server=newServerSocket(4331);
}
catch(IOExceptione1){
System.out.println(e1);
}
try{
System.out.println("等待客户呼叫");
you=server.accept();//堵塞状态,除非有客户呼叫
out=newDataOutputStream(you.getOutputStream());
in=newDataInputStream(you.getInputStream());
Stringc=in.readUTF();//in读取信息,堵塞状态
System.out.println("服务器收到:
"+c);
Datenow=newDate();
SimpleDateFormatdateFormat=newSimpleDateFormat("yyyy/MM/ddHH:
mm:
ss");
Stringhehe=dateFormat.format(now);
out.writeUTF(hehe);
Thread.sleep(500);
Thread.sleep(500);
Stringc1=in.readUTF();//in读取信息,堵塞状态
System.out.println("服务器收到:
"+c1+",退出程序");
out.writeUTF("Bye!
");
Thread.sleep(500);
return;
}
catch(Exceptione){
System.out.println("客户已断开"+e);
}
}
}
运行结果:
任务三:
DatagramSocket类和DatagramPacket类练习
编写一个数据报通信程序,实现简单的聊天功能。
基本要求:
两人一组编写完整程序。
为了给大家减轻负担,Swing部分的代码已给出。
(请同学们到作业管理系统下载Lab8.zip中的UDPmessage.java)
程序代码如下:
importjava.awt.*;
importjava.awt.event.*;
importjava.io.IOException;
import.*;
importjavax.swing.*;
publicclassUDPmessageextendsJFrameimplementsActionListener,Runnable{
privateJTextAreatext;
privateJTextFieldipText;
privateJTextFieldsendText;
privateJButtonbutton;
privateDatagramSocketsocket;
privateJScrollBarvsBar;
Threadthread;
publicUDPmessage(){
setTitle("UDP聊天程序");
setBounds(100,100,400,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(newBorderLayout());
text=newJTextArea();
text.setEditable(false);
JScrollPanetextPanel=newJScrollPane(text);
vsBar=textPanel.getVerticalScrollBar();
add(textPanel,BorderLayout.CENTER);
JPanelpanel=newJPanel();
BorderLayoutpanelLayout=newBorderLayout();
panelLayout.setHgap(5);
panel.setLayout(panelLayout);
ipText=newJTextField("172.17.90.216");
panel.add(ipText,BorderLayout.WEST);
sendText=newJTextField();
panel.add(sendText,BorderLayout.CENTER);
button=newJButton("发送");
panel.add(button,BorderLayout.EAST);
add(panel,BorderLayout.SOUTH);
setVisible(true);
server();
button.addActionListener(this);
}
privatevoidserver(){
thread=newThread(this);
thread.start();
}
publicvoidactionPerformed(ActionEventev){
try{
bytebuffer[]=(InetAddress.getLocalHost().getHostAddress()+"\n"+sendText.getText().trim()+"\n").getBytes();
InetAddressaddress1=InetAddress.getByName(ipText.getText().trim());
InetAddressaddress2=InetAddress.getLocalHost();
DatagramPacketdatapack=newDatagramPacket(buffer,buffer.length,address1,8888);
DatagramSocketmaildata=newDatagramSocket();
maildata.send(datapack);
text.append(InetAddress.getLocalHost().getHostAddress()+"\n"+sendText.getText().trim()+"\n");
sendText.setText(null);
}catch(Exceptionee){
ee.printStackTrace();
}
}
publicvoidrun(){
DatagramPacketpack=null;
DatagramSocketmaildata=null;
byte[]data=newbyte[8192];
try{
pack=newDatagramPacket(data,data.length);
maildata=newDatagramSocket(8888);
}catch(Exceptionee){
ee.printStackTrace();
}
while(true){
if(maildata==null)
break;
else
try{
maildata.receive(pack);
Stringmessage=newString(pack.getData(),0,pack.getLength());
text.append(message);
}catch(Exceptionee){
ee.printStackTrace();
}
}
}
publicstaticvoidmain(Stringargs[]){
JFrameframe=newUDPmessage();
}
}
运行结果如下:
任务四:
传输对象输入与输出流
现有一个Student类(请同学们到作业管理系统下载Lab8.zip):
程序实现:
从服务器端传输一个Student对象到客户端
基本要求:
使用Socket类和ServerSocket类实现
客户端程序运行结果如图所示:
Client.java
import.*;
publicclassClient
{
publicstaticvoidmain(Stringargs[])
{
DatagramPacketpack=null;
DatagramSocketmail_data=null;
bytedata[]=newbyte[8192];
try
{pack=newDatagramPacket(data,data.length);
mail_data=newDatagramSocket(3224);
}
catch(Exceptione){};
try
{mail_data.receive(pack);
Stringmessage=newString(pack.getData(),0,pack.getLength());
System.out.println(message);
}
catch(Exceptione){}