文章目录
setName() getName() : 设置和得到线程的名字
public class TestSetNameAndGetName{
public static void main(String[] args){
Student s1 = new Student("刘玄德",777,"雌雄双股剑");
Student s2 = new Student("关云长",666,"青龙偃月刀");
Student s3 = new Student("张翼德",555,"AK47");
s1.start();
s2.start();
s3.start();
}
}
/*
public class Thread{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
*/
class Student extends Thread{
int age;
String blood;
public Student(String name,int age,String blood){
setName(name);
this.age = age;
this.blood = blood;
}
@Override
public void run(){
for(int i = 0;i<age;i++){
System.out.println("我叫"+getName()+" 手持"+blood);
}
}
}
static activeCount() : 得到程序当中所有活跃线程的总数 ()
活跃线程 = 就绪 + 运行 + 阻塞
public class TestActiveCount{
public static void main(String[] args){
int x = (int)(Math.random()*5) + 5;
for(int i = 0;i<x;i++){
EtoakThread et = new EtoakThread();
et.start();
}
while(true){
System.out.println(Thread.activeCount());//活跃线程的总数
}
}
}
class EtoakThread extends Thread{
@Override
public void run(){
for(int i = 0;i<666;i++){
System.out.println("洗刷刷 洗刷刷 哦哦~");
}
}
}
setDaemon() : 设置线程成为守护线程
- 守护线程 : 守护线程为其它线程提供服务 当程序当中只有守护线程的时候 守护线程会自行结束~
- 最著名的守护线程叫:GC
public class TestSetDaemon{//set呆萌(true)
public static void main(String[] args){
GYJJ jj = new GYJJ();
jj.setDaemon(true);//设置成为守护线程的操作必须早于它自身的start();
//否则不但会设置失败 还会触发运行时异常
jj.start();
jj.setPriority(1);//守护线程具有较低的优先级 以防止它和核心业务争抢时间片
for(int i = 0;i<888;i++){
System.out.println("西天取经上大路 一走就是几万里~");
}
}
}
class GYJJ extends Thread{
@Override
public void run(){
while(true){//守护线程通常要有无限循环 防止其过早消亡
System.out.println("你这泼猴儿~");
}
}
}
interrupt() : 中断 打断 线程的阻塞状态
sleep() join()
public class TestInterrupt{
public static void main(String[] args)throws Exception{
EtoakThread et = new EtoakThread();
et.start();
//Thread.sleep(5000);
//当前线程(主线程) 主动出手 中断 et 线程的阻塞状态
et.interrupt();
}
}
//sleep一执行就去阻塞了 不能一直执行~
class EtoakThread extends Thread{
@Override
public void run(){
try{
sleep(999999999999999L);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("吖!神清气爽吖!");
}
}
static currentThread() : 得到正在运行状态的那个线程对象~
在主方法当中用于得到主线程的线程对象~
public class TestCurrentThread1{
public static void main(String[] args){
EtoakThread et = new EtoakThread();
et.start();
et.setPriority(1);
Thread main = Thread.currentThread();
main.setPriority(10);
while(true){
System.out.println("全世界~");
}
}
}
class EtoakThread extends Thread{
@Override
public void run(){
while(true){
System.out.println("侬好哇~");
}
}
}
在其它线程当中用于得到主线程的线程对象~
public class TestCurrentThread1Again{
public static void main(String[] args){
Thread main = Thread.currentThread();//主线程
EtoakThread et = new EtoakThread(main);
et.start();
et.join();
while(true){
System.out.println("醉里挑灯看剑");
}
}
}
class EtoakThread extends Thread{
Thread main;
public EtoakThread(Thread main){
this.main = main;
}
@Override
public void run(){
main.join();
//et线程想要邀请主线程优先执行
while(true){
System.out.println("梦回吹角连营");
}
}
}
在run()调用的其它方法中 用来得到当前线程是谁~
引例: 周老师没钱吃饭了,为学习Java的同学排错,排一个错收一个包子
我们当前的课题 static currentThread()
它的调用绝对不该直接出现在run() 当中 因为返回的线程等价于this
同时此案例涉及:
- 单例模式
- 多线程高并发的场景下 如何选择键值对集合 ConcurrentHashMap
- join() / CountDownLatch
关于CountDownLatch
- 作用:CountDownLatch允许一个或者多个线程去等待其他线程完成操作。
- 构造方法:CountDownLatch接收一个int型参数,表示要等待的工作线程的个数,当然也不一定是多线程,在单线程中可以用这个int型参数表示多个操作步骤。
CountDownLatch 提供了一些方法:
//JayZhou老师 排错收包子 长清大素包~
import java.util.*;
import java.util.concurrent.*;//ConcurrentHashMap & CountDownLatch~
public class TestCurrentThread2{
static CountDownLatch latch = new CountDownLatch(3);//插销?
public static void main(String[] args)throws Exception{
Student s1 = new Student("小翔");
Student s2 = new Student("小俐");
Student s3 = new Student("小黑");
s1.start();
s2.start();
s3.start();
latch.await();//等待插销都被打开~
/*
s1.join();
s2.join();
s3.join();
*/
System.out.println("周老师的账本信息如下:");
//周老师决定 程序结束前 查账 看看收获如何~
Teacher tea = Teacher.getOnly();//得到老师对象 才能去访问那个map
tea.map.forEach((k,v)->System.out.println(k+":"+v));
}
}
class Student extends Thread{
public Student(String name){
setName(name);//Thread类的setName方法 给线程设置名字
}
public void run(){
System.out.println("我叫:"+getName() + "我要好好学习 但是遭遇了问题~准备问老师");
Teacher tea = Teacher.getOnly();
int x = (int)(Math.random()*3)+2;//2-4
for(int i = 0;i<x;i++){
tea.hdwt();
}
TestCurrentThread2.latch.countDown();//打开一个插销~
}
}
class Teacher{
//多线程高并发的场景下 我们如何选择键值对集合
Map<String,Integer> map = new ConcurrentHashMap<>();//周老师心里有本帐 记录人名和欠他包子个数的对应关系
private Teacher(){}
private static Teacher only = new Teacher();
public static Teacher getOnly(){
return only;
}
public void hdwt(){
//hdwt() 需要知道 是哪个线程调用的hdwt()
Thread dqxc = Thread.currentThread();//得到当前线程对象
String name = dqxc.getName();
System.out.println("认真的解答"+name+"同学的问题~");
//记账!
if(map.containsKey(name)){
Integer bzgs = map.get(name);
map.put(name,bzgs+1);//多次put的时候如果相同的主键 值会替换~
}else{
map.put(name,1);
}
}
}