多线程

实验名称 实验六、多线程 日期 2020年 07 月02 日
一、实验目的:
1、掌握线程的创建。
2、掌握线程的调度。
3、掌握线程的同步。
4、了解线程池的使用。
二、实验环境:

PC+Windows10+Eclipse

三、实验内容:
(写出主要的内容)
1、设有一个银行账户,里面有2000元钱。该账户归tom和jack两个人共同所有。每个人每 次可以取100元钱。编写一个类BankAccount表示银行账户,void withdraw(int count)方法表 示取钱,int getbalance()方法用来获取银行账户余额。创建两个线程分别表示tom和jack两 个人。要求输出取钱的过程,以及每次取钱后的账户余额。 为了更好的模拟多线程的交错运行效果,可以每次取钱之前让线程暂停20毫秒。运行结果如下图。

代码:

package 实验六;
public class Count implements Runnable{
	int money=2000;
	int Getmoney() {
		money=money-100;
		return money;
	}
	public void run() {
		while(this.money>100) {
			synchronized(this) {
				try {
					Thread.sleep(20);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName()+" withdraw 100 balance left "+Getmoney());
		}
	}
	public static void main(String[] args) {
		Count a=new Count();
		Thread t1=new Thread(a);
		t1.setName("Tom");
		Thread t2=new Thread(a);
		t2.setName("Jack");
		t1.start();
		t2.start();
	}

}

2、计算0~999的和,要求使用多线程的方法,第一个线程计算前500个数的和,第二个线 程计算后500个数的和。然后将两个计算结果相加。第一个线程名为thread1,第二个线程名 为thread2。注意:在计算最终结果之前,必须确保两个线程都已经计算完成。程序运行结果如下:

代码:

package 实验六;
public class ThreadAdd {
	public static void main(String[] args) {
		int sum;
		Thread1 t1s=new Thread1();
		Thread2 t2s=new Thread2();
		Thread t1=new Thread(t1s);
		Thread t2=new Thread(t2s);
		t1.setName("thread1");
		t2.setName("thread2");
		t1.start();
		try {
			t1.join();
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		t2.start();
		try {
			t2.join();
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		sum=t1s.get()+t2s.get();
		System.out.println("最终结果为:"+sum);
	}

}
class Thread1 implements Runnable{
		private int sum1=0;
		public void run() {
			for(int i=0;i<500;i++) {
				sum1+=i;
			}
			System.out.println("thread1计算完成  结果为:"+sum1);
		}
		public int get() {
			return sum1;
		}
	}
class Thread2 implements Runnable{
		private int sum2=0;
		public void run() {
			for(int i=500;i<1000;i++) {
				sum2+=i;
			}
			System.out.println("thread2计算完成  结果为:"+sum2);
		}
		public int get() {
			return sum2;
		}
	}

3、编程模拟售票系统,模拟多个窗口(至少4个)同时出售100张车票的情况;用实现Runnable接口的方法实现多线程。程序运行结果如下:

代码:

public class Soldticket
{
		public static void main(String[] args) {
			TicketSell t1 = new TicketSell();
			TicketSell t2 = new TicketSell();
			TicketSell t3 = new TicketSell();
			TicketSell t4 = new TicketSell();
			t1.setName("窗口1");
			t2.setName("窗口2");
			t3.setName("窗口3");
			t4.setName("窗口4");
			t1.start();
			t2.start();
			t3.start();
			t4.start();
	}
}
class TicketSell extends Thread{
	private static int ticket = 100;
	@Override
	public void run() {
		while(true){
			synchronized (TicketSell.class) {
				if(ticket>=0){
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(this.getName()+" "+"剩余 "+ticket+" 张票!");
					ticket--;
				}else{
					break;
				}
			}
		}
	}
}

4、使用多线程同步和互斥方式解决5个哲学家问题。
代码:

public class Eating
{
	public boolean[] isUsing=new boolean[5];
	public synchronized void takeChopsticks(int index){
		while(isUsing[index]||isUsing[(index+1)%5]){
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		isUsing[index]=true;
		isUsing[(index+1)%5]=true;
		System.out.println("哲学家"+index+"拿起筷子");
	}
	public synchronized void putChopsticks(int index){
		isUsing[index]=false;
		isUsing[(index+1)%5]=false;
		System.out.println("哲学家"+index+"放下筷子");
		notify();
	}
}
class Philosopher implements Runnable{
	private int index;
	public static Eating chop=new Eating();
	public Philosopher(int index) {
		this.index = index;
	}
	public synchronized void thinking(){
		System.out.println("哲学家"+Thread.currentThread().getName()+"在思考");
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public synchronized void eating(){
		System.out.println("哲学家"+index+"在吃饭");
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Override
	public void run() {
// TODO Auto-generated method stub
		while(true){
			thinking();
			chop.takeChopsticks(index);
			eating();
			chop.putChopsticks(index);
		}
	}
}
public class Philosopher
{
	public class Philosopher implements Runnable{
		private int index;
		public  Eating chop=new Eating();
		public Philosopher(int index) {
			this.index = index;
		}
		public synchronized void thinking(){
			System.out.println("哲学家"+Thread.currentThread().getName()+"在思考");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		public synchronized void eating(){
			System.out.println("哲学家"+index+"在吃饭");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		@Override
		public void run() {
			while(true){
				thinking();
				chop.takeChopsticks(index);
				eating();
				chop.putChopsticks(index);
			}
		}
	}
}
public class test
{
	public static void main(String[] args) {
		Philosopher p1=new Philosopher(0);
		Philosopher p2=new Philosopher(1);
		Philosopher p3=new Philosopher(2);
		Philosopher p4=new Philosopher(3);
		Philosopher p5=new Philosopher(4);
		new Thread(p1,"0").start();
		new Thread(p2,"1").start();
		new Thread(p3,"2").start();
		new Thread(p4,"3").start();
		new Thread(p5,"4").start();
	}
}

四、心得体会:
通过此次实验,知道了线程也称为轻型进城,是处理器调度的基本单位,灵活使用多线程进行程序设计,可以有效地简化设计任务,提高程序执行效率;掌握了线程的创建;掌握了线程的调度;掌握了线程的同步;了解了线程池的使用。创建进程时,run()方法必须重写,虽然run()方法事线程体,但不能直接调用run()方法,而是通过调用start()方法来启动线程。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值