实验目的:理解多线程的概念,掌握创建、管理和控制Java线程对象的方法,包括创建Java线程对象、改变线程状态、设置线程优先级及控制线程调度等方法,掌握实现线程互斥和线程同步的方法。
实验内容:
1、编写一个有两个线程的程序,第一个线程用来计算1~100之间的偶数及个数,第二个线程用来计算1-100之间的偶数及个数。
Main类:
package cn.qi.text51;
public class Main {
public static void main(String[] args) {
MyThread t1 = new MyThread("线程1");
MyThread t2 = new MyThread("线程2");
t1.start();
t2.start();
}
}
MyThread类:
package cn.qi.text51;
public class MyThread extends Thread{
MyThread(String s){
super(s);
}
@Override
public void run() {
int sum=0;
String s=getName()+"算出1-100之间的偶数有:";
for (int i=1;i<=100;i++){
if(i%2==0){
s += i + " ";
sum++;
}
}
System.out.println(s);//用数组记录,最后一个线程的统一输出
System.out.println(getName()+"算出1-100之间偶数总数: "+sum);
}
}
运行结果:
2、编写一个Java应用程序,在主线程中再创建两个线程,要求线程经历四种状态:新建,运行、中断和死亡。按模板要求,将【代码1】~【代码8】替换为Java程序代码。
class Tortoise extends Thread
{ int sleepTime=0, liveLength=0;
public Tortoise(String name,int sleepTime, int liveLength)
{
this.sleepTime=sleepTime;
this.liveLength=liveLength;
【代码1】 // 设置线程的名字为name
}
public void run()
{ while (true )
{
liveLength--;
System.out.println("@_@");
try{
【代码2】 // 让线程调用sleep()方法进入中断状态
}
catch (InterruptedException e) {}
if (liveLength<=0 )
{
System.out.println(getName()+"进入死亡状态\n");
【代码3】 // 结束run()方法的语句
}
}
}
}
class Rabit extends Thread
{
int sleepTime=0, liveLength=0;
public Rabit(String name,int sleepTime, int liveLength)
{
【代码4】 // 调用父类构造函数,设置线程的名字为name
this.sleepTime=sleepTime;
this.liveLength=liveLength;
}
public void run()
{
while (true )
{
liveLength--;
System.out.println("*_*");
try{
sleep( sleepTime);
}
catch (InterruptedException e) {}
if (liveLength<=0 )
{
System.out.println(getName()+"进入死亡状态\n");
break;
}
}
}
}
public class ThreadExample
{
public static void main(String a[])
{
Rabit rabit;
rabit =【代码5】 // 新建线程rabit
Tortoise tortoise =【代码6】 // 新建线程tortoise
【代码7】 // 启动线程tortoise
【代码8】 // 启动线程rabit
}
}
class Tortoise extends Thread
{ int sleepTime=0, liveLength=0;
public Tortoise(String name,int sleepTime, int liveLength)
{
super(name);//设置线程的名字为name
this.sleepTime=sleepTime;
this.liveLength=liveLength;
}
public void run()
{ while (true )
{
liveLength--;
System.out.println("@_@");
try{
sleep(sleepTime); // 让线程调用sleep()方法进入中断状态
}
catch (InterruptedException e) {}
if (liveLength<=0 )
{
System.out.println(getName()+"进入死亡状态\n");
break; // 结束run()方法的语句
}
}
}
}
class Rabit extends Thread
{
int sleepTime=0, liveLength=0;
public Rabit(String name,int sleepTime, int liveLength)
{
super(name); // 调用父类构造函数,设置线程的名字为name
this.sleepTime=sleepTime;
this.liveLength=liveLength;
}
public void run()
{
while (true )
{
liveLength--;
System.out.println("*_*");
try{
sleep( sleepTime);
}
catch (InterruptedException e) {}
if (liveLength<=0 )
{
System.out.println(getName()+"进入死亡状态\n");
break;
}
}
}
}
public class ThreadExample
{
public static void main(String a[])
{
Rabit rabit;
rabit =new Rabit("rabit", 1, 1); // 新建线程rabit
Tortoise tortoise =new Tortoise("tortoise", 1, 1); // 新建线程tortoise
tortoise.start();// 启动线程tortoise
rabit.start();// 启动线程rabit
}
}
运行结果:
*3、编写Java应用程序模拟5个人排队买票。售票员只有1张五元的钱,电影票五元钱一张。假设5个人的名字及排队顺序是:赵、钱、孙、李、周。“赵”拿1张二十元的人民币买2张票,“钱”拿1张二十元的人民币买1张票,“孙”1张十元的人民币买1张票,“李”拿1张十元的人民币买2张票,“周”拿1张五元的人民币买1张票。
要求售票员按如下规则找赎:
(1)二十元买1张票,找零:1张十元;不许找零2张五元。
(2)二十元买1张票,找零:1张十元,1张五元;不许找零3张五元。
(3)十元买一张票,找零1张五元。
MyThread类:
package cn.qi.text53;
public class MyThread extends Thread{
static int five = 1;
static int ten = 0;
static int twenty = 0;
int money = 0;
int ticket = 0;
MyThread(String name,int money,int ticket){
super(name);
this.money = money;
this.ticket = ticket;
}
@Override
public void run() {
if(getName().equals("赵")){
synchronized (MyThread.class){
twenty++;//都提前把钱给售票员
int time = 0;//判断是否是第一次,若time>0此则表示是被唤醒的,不需要再次输出来买票需等待
while(true){//循环来确保被唤醒一次后若还是需要等待不会不等待
if(ten<1){
if(time == 0) System.out.println("赵来买票但找零不够,需要等等,此时还有"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
try {
MyThread.class.wait();//等待需要前面加对象
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
time++;
}
if(ten>=1){
ten--;
MyThread.class.notifyAll();//唤醒该对象下的所有线程
System.out.println("赵买票成功,此时还剩"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
break;
}
}
}
}
else if(getName().equals("钱")){
synchronized (MyThread.class){
twenty++;
int time = 0;
while(true){
if(ten<1||five<1){
if(time == 0) System.out.println("钱来买票但找零不够,需要等等,此时还有"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
try {
MyThread.class.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
time++;
}
if(ten>=1&&five>=1){
ten--;
five--;
MyThread.class.notifyAll();
System.out.println("钱买票成功,此时还剩"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
break;
}
}
}
}
else if(getName().equals("孙")){
synchronized (MyThread.class){
ten++;
int time = 0;
while(true){
if(five<1){
if(time==0) System.out.println("孙来买票但找零不够,需要等等,此时还有"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
try {
MyThread.class.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
time++;
}
if(five>=1){
five--;
MyThread.class.notifyAll();
System.out.println("孙买票成功,此时还剩"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
break;
}
}
}
}
else if(getName().equals("李")){
synchronized (MyThread.class){
ten++;
MyThread.class.notifyAll();
System.out.println("李买票成功,此时还剩"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
}
}
else if(getName().equals("周")){
synchronized (MyThread.class){
five++;
MyThread.class.notifyAll();
System.out.println("周买票成功,此时还剩"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
}
}
}
}
Main类:
package cn.qi.text53;
public class Main {
public static void main(String[] args) throws InterruptedException {
MyThread t1 = new MyThread("赵",20,2);
MyThread t2 = new MyThread("钱",20,1);
MyThread t3 = new MyThread("孙",10,1);
MyThread t4 = new MyThread("李",10,2);
MyThread t5 = new MyThread("周",5,1);
t1.start();
Thread.sleep(1000);//通过sleep来保证排队顺序
t2.start();
Thread.sleep(1000);
t3.start();
Thread.sleep(1000);
t4.start();
Thread.sleep(1000);
t5.start();
}
}
运行结果: