JavaEE学习笔记-(4)线程-1

线程

1.理解

​ 程序:程序:保存在物理介质[光盘 软盘…]中的代码片段

​ 进程:一旦程序运行起来 就变成了操作系统当中的一个进程 = 进行当中的程序~

​ 线程:程序当中一条独立的执行线索

​ 时间片:一个线程去执行的时间单位

​ 为什么要使用多线程:根本原因 为了让程序学会同时处理多个不同的任务

2.线程的五大状态,即生命周期

新生		   就绪		      运行		消亡
Born		Runnable		Running		Dead

			 阻塞
			 Blocking

3.线程的实现方法

1.extends Thread
    @Override
    public void run(){
    	//布置线程的任务
	}
//启动线程调用的是start() 而不是run()!!!

2.implements Runnable //实现Runnable接口
    public void run(){
    	//布置线程的任务
	}
//不能直接start() 必须自己new一个Thread对象 把他当做参数传入
    

//用两种方式 实现两个线程
public class cao22{
	public static void main(String[] args){
		ThreadOne one = new ThreadOne();
		one.start();

		ThreadTwo two = new ThreadTwo();
		Thread t = new Thread(two);
		t.start();
	}
}

class ThreadOne extends Thread{
	@Override
	public void run(){
		for(int i=1;i<=26;i++)
			System.out.println(i);
	}
}

class ThreadTwo implements Runnable{
    //同志们,这种方式就可以使该类不局限于单一继承的缺点
	@Override
	public void run(){
		for(char i='a';i<='z';i++)
			System.out.println(i);
	}
}

4.控制线程的方法


0. setPriority(int) : 设置线程优先级别
		可选范围1-10 默认优先级为5
		线程优先级越高 代表抢到时间片的概率越高~

1. static sleep(long) : 让当前线程休眠指定的毫秒数~
		
2. static yield() : 让当前线程放弃已经持有的时间片 直接返回就绪状态

3. join() : 让当前线程邀请另一个线程优先执行 
		在被邀请的线程执行结束之前 主动邀请别人的当前线程不再执行 一直阻塞

		一个主动邀请别人的线程: 当前处于运行状态的线程 = join写在谁的线程体当中
		被邀请优先执行的线程:    主动调用方法的那个线程

	*:程序当中未必只有这两个线程 弄清楚其它线程与他们的关系

	*: 主动进入阻塞状态的方法 都需要进行异常处理
		因为Ta们都有throws InterruptedException的声明 而这时一个非运行时异常 必须处理

	*: 线程章节所有的静态方法 不要关注谁调用方法 而要关注
		调用出现在谁的线程体当中 出现在哪个线程体当中 就是操作哪个线程


练习

	有一个师傅线程 打印999次 "去西天西经...."
	有一个猴哥线程 打印888次 "俺老孙来也~"
	有一个八戒线程 打印777次 "回高老庄!!!"
	有一个沙僧线程 打印666次 "大师兄不好了,师傅被妖怪抓走了~"
要求
	*:请师傅的优先级设置为最低:setPriority(int);
	*:猴哥前三次得到时间片都会主动放弃:yield();
	*:八戒很懒 在执行操作之前要先休眠300毫秒:sleep(long);
	*:废物沙僧,猴哥上之前,沙僧绝对不上。

public class BigOne{
    
	public static void main(String[] args){
		SF sf = new SF();
		sf.setPriority(1);
		sf.start();
		
		WK wk = new WK();
		wk.start();
		
		WN wn = new WN();
		wn.start();
		
		WJ wj = new WJ(wk);
		wj.start();
	}
}
class SF extends Thread{
	@Override
	public void run(){
		for(int i = 0;i<999;i++){
			System.out.println("去西天西经....");
		}
	}
}
class WK extends Thread{
	@Override
	public void run(){
		yield();
		yield();
		yield();
		for(int i = 0;i<888;i++){
			System.out.println("俺老孙来也~");
		}
	}
}
class WN extends Thread{
	@Override
	public void run(){
		try{
			sleep(300);
		}catch(Exception e){
			e.printStackTrace();
		}
		for(int i = 0;i<777;i++){
			System.out.println("回高老庄!!!");
		}
	}
}
class WJ extends Thread{
	WK hg;
	public WJ(WK hg){
		this.hg = hg;
	}
	@Override
	public void run(){
		try{
			hg.join();
		}catch(Exception e){
			e.printStackTrace();
		}
		for(int i = 0;i<666;i++){
			System.out.println("大师兄不好了,妖怪呗师傅抓走了~");
		}
	}
}

5.线程其他的常用方法

1.setName() : 设置线程的名字
2.getName() : 得到线程的名字
3.static activeCount():得到程序当中所有活跃线程的总数
		活跃线程 = 就绪 + 运行 + 阻塞
		注意 : 得到的结果一定是加上主线程的结果,即在数量上为原有结果+1
4.setDaemon() : 设置线程成为守护线程
		守护线程是为其它线程提供服务的
		当程序当中只有守护线程的时候,守护线程会自行结束
5.interrupt() : 中断/打断线程的阻塞状态
		一般要配合sleep() join()使用
6.static currentThread() : 得到正在运行状态的那个线程对象
		1.在main方法中,得到主线程的线程对象
		2.在run()调用的其他方法中,得到当前线程是谁(可以理解为王者荣耀的大龙,此		  时此刻哪个线程在打他)
		3.此方法不应该出现在run()中,返回的线程就相当于this

王者荣耀,主宰(也就是大龙),需要计算此时此刻 谁在打他,打了几次

import java.util.*;
import java.util.concurrent.*;//ConcurrentHashMap  & CountDownLatch~
public class TestCurrent{
	public static void main(String[] args) throws Exception{
		Player p1 = new Player("李白");
		Player p2 = new Player("韩信");
		Player p3 = new Player("露娜");

		p1.start();
		p2.start();
		p3.start();

		p1.join();
		p2.join();
		p3.join();

		System.out.println("大龙挨打的过程如下:");

		Dragon dragon = Dragon.getOnly();//得到老师对象 才能去访问那个map
		Set<String> ks = dragon.map.keySet();
		for(String k : ks){
			System.out.println(k + " : " + dragon.map.get(k));
		}

	}
}
class Dragon{//大龙线程
	//多线程高并发的场景下 选择ConcurrentHashMap最合适
	Map<String,Integer> map = new ConcurrentHashMap<>();//大龙可以知道 是哪个玩家打的他 以及名字和次数之间的关系
	private Dragon(){}
	private static Dragon only = new Dragon();
	public static Dragon getOnly(){
		return only;
	}
	public void count(){//计算玩家与次数~
		Thread dqxc = Thread.currentThread();//得到当前线程对象
		String name = dqxc.getName();
		System.out.println("是"+name+"在打我!!!!!!!!~");

		//计算
		Integer v = 1;
		if(map.containsKey(name))
			v = map.get(name) + 1;

		map.put(name,v);
	}

}
class Player extends Thread{ //玩家线程
	public Player(String name){
		setName(name);// 继承父类Thread 得到 setName()方法
	}
	public void run(){
		System.out.println("我是" + getName() + ", 我要去打大龙~~~");
		Dragon dragon = Dragon.getOnly();
		int x = (int)(Math.random()*3)+2;//2-4
		for(int i = 0;i<x;i++){
			dragon.count();
		}

	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值