Java_多线程-多线程基础

1 多线程的实现方式
1.1 继承Thread类
//多线程的实现方式一:继承Thread类
class KS extends Thread{
	@Override
	public void run() {
		super.run();
		System.out.println("开始烧开水");
		try {
			Thread.sleep(5000);//.sleep()休眠时间5000毫秒
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("水烧开了");
	}
}
class XBZ extends Thread {
	@Override
	public void run() {
		super.run();
		System.out.println("开始洗杯子");
		try {
			for(int i=1;i<=3;i++){
				Thread.sleep(1000);//休眠时间1000毫秒
				System.out.println("第"+i+"个杯子洗好了");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("所有杯子洗好了");
	}

}
public class thread {
	public static void main(String[] args) {
		KS ks = new KS();//烧开水 实体类对象
		XBZ xbz = new XBZ();//洗杯子 实体类对象
		ks.start();//启动线程
		xbz.start();//启动线程
	}
	
}

开始烧开水
开始洗杯子
第1个杯子洗好了
第2个杯子洗好了
第3个杯子洗好了
所有杯子洗好了
水烧开了
1.2 实现Runnable接口

//多线程的实现方式二:实现Runnable接口
class KS1 implements Runnable{
	@Override
	public void run() {
		System.out.println("开始烧开水");
		try {
			Thread.sleep(5000);//.sleep()休眠时间5000毫秒
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("水烧开了");
	}
}
class XBZ1 implements Runnable {
	@Override
	public void run() {
		System.out.println("开始洗杯子");
		try {
			for(int i=1;i<=3;i++){
				Thread.sleep(1000);//休眠时间1000毫秒
				System.out.println("第"+i+"个杯子洗好了");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("所有杯子洗好了");
	}

}
public class runnable {
	public static void main(String[] args) {
		KS1 ks = new KS1();
		XBZ1 xbz = new XBZ1();
		Thread t1 = new Thread(ks);//将实体类对象通过Thread的构造传给Thread类对象
		Thread t2 = new Thread(xbz);//将实体类对象通过Thread的构造传给Thread类对象
		t1.start();//启动字线程一
		t2.start();//启动字线程二
	}
}

开始烧开水
开始洗杯子
第1个杯子洗好了
第2个杯子洗好了
第3个杯子洗好了
所有杯子洗好了
水烧开了
2 多线程卖票的例子
2.1 同步方法

class tickets implements Runnable{//实体类
	int num=10;//票
   boolean flag=true;
	@Override
	public void run() {
		while(flag){
			sales();//调用卖票的方法
		}
	}
	public synchronized void sales(){//synchronized 这个方法开始执行就必需一直执行直到结束为止
		if(num>0){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"卖出票-->剩下票:"+num);
			num--;
		}else{
			flag=false;
		}
	}

}
public class ticketLX {
	public static void main(String[] args) {
		tickets ticket = new tickets();
		
		Thread t1 = new Thread(ticket);//将实体类对象通过Thread的构造传给Thread类对象
		Thread t2 = new Thread(ticket);
		Thread t3 = new Thread(ticket);
		t1.setName("窗口一");//设置线程名字
		t2.setName("窗口二");
		t3.setName("窗口三");
		
		t1.start();//启动子线程一
		t2.start();//启动子线程二
		t3.start();//启动子线程三
	}
}

窗口一卖出票-->剩下票:10
窗口三卖出票-->剩下票:9
窗口三卖出票-->剩下票:8
窗口三卖出票-->剩下票:7
窗口三卖出票-->剩下票:6
窗口三卖出票-->剩下票:5
窗口三卖出票-->剩下票:4
窗口三卖出票-->剩下票:3
窗口三卖出票-->剩下票:2
窗口二卖出票-->剩下票:1
2.2 同步方法
class ticketsTwo implements Runnable{//实体类
	int num=10;//票
	int i=1;
   boolean flag=true;
	@Override
	public void run() {
		while(flag){
			sales();//调用卖票的方法
		}
	}
	public synchronized void sales(){//synchronized 这个方法开始执行就必需一直执行直到结束为止
		
			if(num>0){
				
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"卖出1张票-->:总卖票数为"+i);
				num--;
				i++;
			}else {
				flag=false;
			}
		}
}
public class ticketLX2 {
	public static void main(String[] args) {
		ticketsTwo ticket = new ticketsTwo();
		
		Thread t1 = new Thread(ticket);//将实体类对象通过Thread的构造传给Thread类对象
		Thread t2 = new Thread(ticket);
		Thread t3 = new Thread(ticket);
		t1.setName("窗口一");//设置线程名字
		t2.setName("窗口二");
		t3.setName("窗口三");
		
		t1.start();//启动子线程一
		t2.start();//启动子线程二
		t3.start();//启动子线程三
	}
}
窗口一卖出1张票-->:总卖票数为1
窗口一卖出1张票-->:总卖票数为2
窗口一卖出1张票-->:总卖票数为3
窗口一卖出1张票-->:总卖票数为4
窗口一卖出1张票-->:总卖票数为5
窗口一卖出1张票-->:总卖票数为6
窗口三卖出1张票-->:总卖票数为7
窗口三卖出1张票-->:总卖票数为8
窗口三卖出1张票-->:总卖票数为9
窗口三卖出1张票-->:总卖票数为10
2.3 同步块


class TicketsOne{
	 int tid=1;//第一张票
}
class tickets1 extends Thread {//实体类
	private TicketsOne tt;//拥有票
	boolean flag=true;
   public tickets1(TicketsOne tt) {
		super();
		this.tt = tt;
	}
	public void run() {
		super.run();
		while(flag){
			synchronized (tt){//同步块(不能被同时用的代码)---()里传入对象
				if(tt.tid<=10){//假设票共有10张
					System.out.println(Thread.currentThread().getName()+"卖出1张票-->:总卖票数为"+tt.tid);
					tt.tid++;
				}else {
					flag=false;
				}
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
public class ticketLX2_thread{
	public static void main(String[] args) {
		TicketsOne tt = new TicketsOne();
		
		tickets1 t1 = new tickets1(tt);//实体类对象
		tickets1 t2 = new tickets1(tt);
		tickets1 t3 = new tickets1(tt);
		
		t1.setName("窗口一");//设置线程名字
		t2.setName("窗口二");
		t3.setName("窗口三");
		
		t1.start();//启动子线程一
		t2.start();//启动子线程二
		t3.start();//启动子线程三
	}
}
窗口一卖出1张票-->:总卖票数为1
窗口三卖出1张票-->:总卖票数为2
窗口二卖出1张票-->:总卖票数为3
窗口二卖出1张票-->:总卖票数为4
窗口三卖出1张票-->:总卖票数为5
窗口一卖出1张票-->:总卖票数为6
窗口二卖出1张票-->:总卖票数为7
窗口三卖出1张票-->:总卖票数为8
窗口一卖出1张票-->:总卖票数为9
窗口二卖出1张票-->:总卖票数为10
3 join
3.1 未用join前
package Multithreading;
//.join()  等待线程结束
class join_thread extends Thread{
	@Override
	public void run() {
		super.run();
		for(int i=0;i<10;i++){
			System.out.println(Thread.currentThread().getName()+i);
		}//.currentThread()获得当前的线程    .getName()获得当前线程名字
	}
}
public class join {
	public static void main(String[] args) {
		join_thread j1 = new join_thread();
		join_thread j2 = new join_thread();
		j1.setName("线程一");
		j2.setName("线程二");
		
		j1.start();
		/*try {
			j1.join();//等待子线程一结束后再往下执行
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
		
		j2.start();
		/*try {
			j2.join();//等待子线程二结束后再往下执行  若没有j2.join()则线程二和主线程同步进行
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
		
		for(int i=0;i<10;i++){
			System.out.println("主线程"+i);
		}
	}
}

主线程0
主线程1
主线程2
线程一0
线程一1
主线程3
主线程4
主线程5
主线程6
主线程7
主线程8
主线程9
线程二0
线程一2
线程一3
线程一4
线程一5
线程一6
线程一7
线程一8
线程一9
线程二1
线程二2
线程二3
线程二4
线程二5
线程二6
线程二7
线程二8
线程二9
3.2 使用join

讲上述 join代码块注释去掉

	try {
			j1.join();//等待子线程一结束后再往下执行
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		try {
			j2.join();//等待子线程二结束后再往下执行  若没有j2.join()则线程二和主线程同步进行
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
线程一0
线程一1
线程一2
线程一3
线程一4
线程一5
线程一6
线程一7
线程一8
线程一9
线程二0
线程二1
线程二2
线程二3
线程二4
线程二5
线程二6
线程二7
线程二8
线程二9
主线程0
主线程1
主线程2
主线程3
主线程4
主线程5
主线程6
主线程7
主线程8
主线程9
4中断线程方式
4.1 interrupt
//中断线程方式一
class one extends Thread {
	@Override
	public void run() {
		super.run();
		int i = 1;
		while (true) {
			System.out.println(i++);
			try {
				Thread.sleep(1000);//休眠1000毫秒
			} catch (InterruptedException e) {
				e.printStackTrace();
				return;
			}finally{
				System.out.println("finally");
			}
			System.out.println("其他收尾工作");
		}

	}
}
public class interrupt {
	public static void main(String[] args) {
		one  o = new one();
		o.start();//启动子线程

		//主线程休眠5000毫秒 后中断子线程
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		o.interrupt();//中断子线程
	}
}
1
finally
其他收尾工作
2
finally
其他收尾工作
3
finally
其他收尾工作
4
finally
其他收尾工作
5
java.lang.InterruptedException: sleep interrupted
finally
	at java.lang.Thread.sleep(Native Method)
	at Multithreading.one.run(interrupt.java:11)

注:中断子线程,子线程就停止了

4.2 不报异常的方式中断线程
//中断线程方式二
class one1 extends Thread {
	private boolean flag = true;
	
	public boolean isFlag() {
		return flag;
	}
	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	public void run() {
		super.run();
		int i = 1;
		while (flag) {//flag变量
			System.out.println(i++);
			try {
				Thread.sleep(1000);//休眠1000毫秒
			} catch (InterruptedException e) {
				e.printStackTrace();
				return;
			}finally{
				System.out.println("finally");
			}
			System.out.println("其他收尾工作");
		}
	}
}
public class interrupt2 {
	public static void main(String[] args) {
		one1 o = new one1();
		o.start();//启动子线程

		//主线程休眠5000毫秒 后中断子线程
		try {
			Thread.sleep(5000);//主线程休眠5000毫秒
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		o.setFlag(false);//变相地中断子线程
	}
}

1
finally
其他收尾工作
2
finally
其他收尾工作
3
finally
其他收尾工作
4
finally
其他收尾工作
5
finally
其他收尾工作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值