java--多线程

0x01 java多线程编程方法

在这里插入图片描述

例1:龟兔赛跑
import java.awt.*;
import java.awt.event.*;


public class Hello2 extends Canvas implements Runnable {
	String name;
	int speed;
	int sleepTime;
	final int distance=700;
	int pos=0;
	public Hello2(String n,int s,int t) {
		name=n;speed=s;sleepTime=t;
	}
	
	public static void main(String args[]) {
		Frame m=new Frame("龟兔赛跑");
		m.setLayout(new GridLayout(3,1));
		final Hello2 a1=new Hello2("乌龟",1,40);
		final Hello2 a2=new Hello2("兔子",4,160);
		Button b=new Button("开始");
		m.add(a1);m.add(a2);m.add(b);//添加两个画布和一个按钮
		m.setSize(780,200); 	m.setVisible(true);
		b.addActionListener(new ActionListener() {//对按钮进行监听
			public void actionPerformed(ActionEvent e) {
				new Thread(a1).start();//创建两个线程同时启动
				new Thread(a2).start();
				a1.repaint();	a2.repaint();//repaint()是重绘component的方法;重绘组件,是一个具有刷新效果的方法
			}
		});
	}
	public void paint(Graphics g) {
		g.drawString(name, 20, 20);//画出乌龟和兔子的两个名字
	}
	public void run() {
		long startTime=System.currentTimeMillis();//记录开始时间
		Graphics g=getGraphics();//得到画笔
		while(pos<distance) {
			for(int k=0; k<(int)(1+Math.random()*3);k++) {//k用随机数表示每次一口气跑了几秒
				pos+=speed;
				if(pos>distance)	pos=distance;
				g.fillRect(50,15,pos,10);
			}
			try {//跑了一段休息一会
				Thread.sleep(sleepTime);
			}catch(InterruptedException e) {}
		}
		long spend=System.currentTimeMillis()-startTime;//现在时间-开始时间=最终时间
		javax.swing.JOptionPane.showMessageDialog(null, name+":花费"+spend+"毫秒");//通过消息框输出花费时间
		pos=0;
		repaint();
	}
}


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

0x02 线程资源的同步处理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

例2:过桥问题



class PersonPassBridge extends Thread {
	private Bridge bridge;//桥对象
	String id;//人的标识
	public PersonPassBridge(String id,Bridge b) {
		bridge=b;this.id=id;
	}
	public void run() {
		bridge.getBridge();//等待过桥
		System.out.println(id+"正过桥……");
		try {
			Thread.sleep((int)(Math.random()*1000));
		}catch(InterruptedException e) {}
		bridge.goDownBridge();//下桥
	}
}
	class Bridge{
		private boolean engaged=false;//桥的占用状态
		//synchronized执行某方法时对桥进行加锁
		public synchronized void getBridge() {//取得上桥
			while(engaged) {
				try {
					wait();//等待
				}catch(InterruptedException e) {}
			}
			engaged =true;//占用桥
		}
		public synchronized void goDownBridge() {//下桥
			engaged=false;
			notifyAll();//唤醒其他等待线程
		}
	}

	public class Hello2{
		public static void main(String args[]) {
			Bridge b=new Bridge();
			PersonPassBridge x;
			for(int k=1;k<=6;k++) {
				x=new PersonPassBridge("南边,第"+k+"人",b);
				x.start();
			}
			for(int k=1;k<=5;k++) {
				x=new PersonPassBridge("北边,第"+k+"人",b);
				x.start();
			}
		}
	}
	

输出结果:
在这里插入图片描述

课后练习:利用多线程实现两个会计数的按钮,按钮上的数字随着线程的运行从100开始不断增加. 点击按钮,则相应按钮上的数字停止变化.
import java.awt.*;
import java.awt.event.*;


class CountButton extends Button implements Runnable,ActionListener {
	int count=100;
	boolean flag=true;
	
	public CountButton(String s) {
		super(s);//super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 
				//this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
		addActionListener(this);//按钮监听
	}
	
	public void actionPerformed(ActionEvent e) {
		flag = false;//点击按钮,flag=false,那么while将会停止,即计数停止
	}
	
	public void run() {
		while(flag && count < 10000)
		{
			try {
				this.setLabel(""+ count++);
				Thread.sleep((int)(1000*Math.random()));
			}catch(Exception e) { }
		}
	}
	
}

public class Hello2 extends Frame{
	public Hello2() {
		setLayout(null);//不使用布局管理
		CountButton t1=new CountButton("first");//创建按钮
		t1.setBounds(30,50,80,40);///规定部件的坐标位置和宽度、高度
		add(t1);//添加按钮
		CountButton t2=new CountButton("Second");
		t2.setBounds(130,50,80,40);
		add(t2);
		(new Thread(t1)).start();//创建线程,将计数按钮传递给线程
		(new Thread(t2)).start();
	}
	
	public static void main(String args[]) {
		Frame f=new Hello2();
		f.setSize(250, 150);
		f.setVisible(true);
	}
}

输出结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值