实验5 多线程
一、实验目的
1、掌握多线程的创建方法; 2、掌握多线程的互斥与同步;
二、实验环境
MyEclipse/Eclipse
三、实验内容
(一)基本指导
1、题目:假设有火车票100张,创建10个线程模拟10个售票点,每个售票点100毫秒卖一张票。 打印出售票过程,注意使用synchronized确保同一张票只能卖出一次。
操作步骤:
(1)启动MyEclipse,新建一个Java工程:选择菜单File->New->Java Project,就会弹出创建Java 项目的界面。在创建Java 项目的界面中,Project name的文本框用来输入新创建Java 项目的项目名称,这里我们输入“Experiment5”。单击Finish按钮完成工程的创建。
(2)在Package Explorer窗口中单击工程Experiment5前面的“+”号,在“src”上单击鼠标右键,在弹出菜单中选择New->Class,就会出现创建Java 类界面,在Package中输入“ticket”,在Name中输入“Ticket”,单击Finish按钮完成类的创建。这样就创建了一个名称为Ticket的类。
(3)在Ticket类中输入代码如下:
package ticket; /**
* 票类,定义了票的总数和同步的售票方法 */
public class Ticket {
int ticketNum = 50;
boolean flag = false ; // 定义票是否卖完 public Ticket(){} public Ticket(int num){ this.ticketNum = num; }
public synchronized void sellTicket(Seller s){ if (ticketNum > 0){
System.out.println(\第\ + s.num + \售票点卖出了第\ + ticketNum + \号票……\);
ticketNum--; } else{
flag = true;
24
} } }
(4)在Package Explorer窗口中工程Experiment5下“src”下的“ticket”包上单击鼠标右键,在弹出菜单中选择New->Class,就会出现创建Java 类界面,在Name中输入“Seller”,单击Interfaces后的“Add...”按钮,在弹出的窗口中的“Choose interfaces:”文本框中输入“Runnable”,单击OK按钮返回,单击Finish按钮完成类的创建。这样就创建了一个名称为Seller的类。
(5)在Seller类中输入代码如下:
package ticket; /**
* 售票点类 * */
class Seller implements Runnable{ int num;
Ticket ticket;
public Seller(int num,Ticket ticket){ this.num = num; this.ticket = ticket;
}
@Override
public void run(){ while (!ticket.flag){ /**
* 调用票类的同步方法 */
ticket.sellTicket(this);
try{
Thread.sleep(100); }
catch (InterruptedException e){ e.printStackTrace(); } } } }
(6)在Package Explorer窗口中工程Experiment5下“src”下的“ticket”包上单击鼠标右键,在弹出菜单中选择New->Class,就会出现创建Java 类界面,在Name中输入“SellTicket”,选中“public static void main(String[] args)”复选框,单击Finish按钮完成类的创建。这样就创建了一个名称为SellTicket的主类。
(7)在SellTicket类中输入代码如下:
package ticket;
public class SellTicket {
public static void main(String[] args) {
25
Ticket tickets = new Ticket(100);
for (int i=0;i<10 ;i++ ){
new Thread(new Seller(i,tickets)).start(); } }
}
(8)点击工具栏运行按钮,运行结果如图E5-1所示。
图E5-1 运行结果
2、题目:有三个线程分别输出“A”、“B”、“C”,请用多线编程实现,在屏幕上循环打印5次ABCABC? ,注意由于线程执行的不确定性,要保证这样有序的输出,必须控制好多线程的同步。线程同步有两种基本方法:
? synchronized
? wait,notify,notifyAll
这里采用第一种种方法来解答这道题目,第二种方法留给读者自己实现。 操作步骤:
(1)在Package Explorer窗口中单击工程Experiment5前面的“+”号,在“src”上单击鼠标右键,在弹出菜单中选择New->Class,就会出现创建Java 类界面,在Package中输入“printABC”,在Name中输入“Turn”,单击Finish按钮完成类的创建。这样就创建了一个名称为Turn的类。
(2)在Turn类中输入代码如下:
package printABC; public class Turn {
private String name = \; public String getName() { return name; }
public void setName(String name) { this.name = name; } }
(3)在Package Explorer窗口中工程Experiment5下“src”下的“printABC”包上
单击鼠标右键,在弹出菜单中选择New->Class,就会出现创建Java 类界面,在Name中输入“Printer”,单击Interfaces后的“Add...”按钮,在弹出的窗口中的“Choose interfaces:”文本框中输入“Runnable”,单击OK按钮返回,单击Finish按钮完成类的创建。这样就创建了一个名称为Printer的类。
(4)在Printer类中输入代码如下:
package printABC;
26
public class Printer implements Runnable { }
private String name = \; private Turn turn = null; private int count = 5;
public Printer(String name, Turn turn) { }
@Override
public void run() { }
while (count > 0) { }
synchronized (turn) { }
if (turn.getName().equals(this.name)) { }
System.out.print(name); count--;
if (this.name.equals(\)) { }
turn.setName(\); turn.setName(\); turn.setName(\);
} else if (this.name.equals(\)) { } else if (this.name.equals(\)) {
this.name = name; this.turn = turn;
(5)在Package Explorer窗口中工程Experiment5下“src”下的“printABC”包上单击鼠标右键,在弹出菜单中选择New->Class,就会出现创建Java 类界面,在Name中输入“PrintABC”,选中“public static void main(String[] args)”复选框,单击Finish按钮完成类的创建。这样就创建了一个名称为PrintABC的主类。
(6)在PrintABC类中输入代码如下:
package printABC; public class PrintABC {
public static void main(String[] args) {
Turn turn =new Turn();
new Thread(new Printer(\, turn)).start();
new Thread(new Printer(\, turn)).start(); new Thread(new Printer(\, turn)).start(); }
}
(7)点击工具栏运行按钮,运行结果如图E5-2所示。
27
图E5-2 运行结果
(二)实验练习题
1、基本指导的第2题中使用synchronized方法有没有什么不足之处?请采用第二种方法(使用wait,notify,notifyAll)来解答基本指导的第2题。
2、编写程序,启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5,然后是线程2打印6,7,8,9,10,然后是线程3打印11,12,13,14,15,接着再由线程1打印16,17,18,19,20,以此类推, 直到打印到75为止。
28
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库Java实验指导书(6)在线全文阅读。
相关推荐: