慕课网 深入浅出java多线程

时间:2023-01-27 20:42:53



1.thread常用方法

  java.lang

class:Thread     interface:runnable  

创建线程:

     thread()

     thread(String name)

     thread(Runnable target)

     thread(Runnable target,String name)

方法:void start()    ----------   启动线程

  static void sleep(long millis)    ----------   休眠

  static void sleep(long millis,int nanos) 

  void join()   ----------   使其他线程等待当前线程终止

  void join(long millis)

  void join(long millis,int nanos)

   static void yield( )   ----------   当前运行线程释放处理器资源

获取线程引用: static Thread currendThread()

如何正确停止线程

1.不要用stop方法

2.使用退出标志

3.不要使用interrupt()方法,因为在线程run()中调用sleep(),join(),yeild()方法时,中断状态会被清除,isinterrupe=false


public class ActorThread extends Thread {

public void run(){
System.out.println(getName()+"是一个演员!");
int count = 0;
boolean keepRunning = true;

while(keepRunning){
System.out.println(getName()+"登台演出:"+ (++count));

if(count == 100){
keepRunning = false;
}

if(count%10== 0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println(getName()+"的演出结束了!");
}


public static void main(String[] args){
Thread actor = new ActorThread();
actor.setName("Mr. Thread");

actor.start();

Thread actressThread = new Thread(new Actress(),"Ms. Runnable");
actressThread.start();
}

}


class Actress implements Runnable{

@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"是一个演员!");
int count = 0;
boolean keepRunning = true;

while(keepRunning){
System.out.println(Thread.currentThread().getName()+"登台演出:"+ (++count));

if(count == 100){
keepRunning = false;
}

if(count%10== 0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println(Thread.currentThread().getName()+"的演出结束了!");

}

}

2.实例:隋唐演义(   英雄人物    隋军 .农民军    舞台)

1)KeyPerson   Thread

public class KeyPerson extends Thread {
public void run(){
System.out.println(Thread.currentThread().getName()+"开始战斗!!");
//发送10连击
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"左图右击,攻击隋军");
}
System.out.println(Thread.currentThread().getName()+"结束战斗!!");
}
}

2) army   Runnable

public class ArmyRunnable implements Runnable{
//volatile保证了线程可以正确的读取其他线程写值
volatile boolean keepRunning=true;
public void run(){
System.out.println("开始战斗!!");
while(keepRunning){
//发送五连击
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+"发送攻击["+i+"]");
//让出了处理器时间,下次谁攻击谁还不定
Thread.yield();
}
}
System.out.println("结束战斗!!");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

}

}

3)Stage

public class Stage extends Thread {
public void run(){
ArmyRunnable armyOfSui=new ArmyRunnable();
ArmyRunnable armyOfRev=new ArmyRunnable();
//使用runnable接口创建线程
Thread armyOfSuiDynasty=new Thread(armyOfSui,"隋军");
Thread armyOfRevolt=new Thread(armyOfRev,"农民军");

//启动线程,让军队开始作战
armyOfSuiDynasty.start();
armyOfRevolt.start();

//舞台线程休眠,大家专心观看军队厮杀
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("双方激战,杀出个程咬金!!");

Thread mrcheng=new KeyPerson();
mrcheng.setName("程咬金");

//停止军队作战
armyOfSui.keepRunning=false;
armyOfRev.keepRunning=false;

try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}

//舞台大戏留给关键人物
mrcheng.start();
//所有线程等待程咬金完成
try {
mrcheng.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}

}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Stage stage=new Stage();
stage.start();
}

}


3.互斥同步

互斥:  private final Object lockObj = new Object(); 

synchronized(lockObj)

同步:lockObj.wait();   

             lockObj.notify();

            lockObj.notifyAll();     

wait set: 等待序列

 public void transfer(int from, int to, double amount){

synchronized(lockObj){

// if (energyBoxes[from] < amount)
// return;
//while循环,保证条件不满足时任务都会被条件阻挡
//而不是继续竞争CPU资源
while (energyBoxes[from] < amount){
try {
//条件不满足, 将当前线程放入Wait Set
lockObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}


System.out.print(Thread.currentThread().getName());
energyBoxes[from] -= amount;
System.out.printf("从%d转移%10.2f单位能量到%d", from, amount, to);
energyBoxes[to] += amount;
System.out.printf(" 能量总和:%10.2f%n", getTotalEnergies());
//唤醒所有在lockObj对象上等待的线程
lockObj.notifyAll();
}

}