Java多线程知识总结(补充)

时间:2023-02-26 19:00:14

Java程序每次运行至少启动两个线程:main线程、垃圾收集线程。

Thread类中常用的方法:
currentThread(静态),通过类名Thread直接调用;

判断线程是否启动(存活)
class MyThread implements Runnable{
  public void run(){
    for(int i=0;i<3;i++){
      System.out.println(Thread.currentThread().getName()+"运行………"+i);
    }
  }
}

public class ThreadAliveDemo {

  public static void main(String[] args) {
    MyThread mt = new MyThread();
    Thread t = new Thread(mt);
    System.out.println("线程开始执行之前……"+t.isAlive());
    t.start();
    for(int i=0;i<5;i++){
      System.out.println("等待……"+i);//i值的不同,最后运行结果不同
    }

    System.out.println("线程开始执行之后……"+t.isAlive());
    for(int i=0;i<3;i++){
      System.out.println("main运行……"+i);
    }
    System.out.println("代码执行之后……"+t.isAlive());
  }
}

主线程有可能比其他行程先执行完,其他线程不会受到任何影响,不会随着主线程的结束而结束。


线程的强制执行
class MyThread implements Runnable{
  public void run(){
    for(int i=0;i<20;i++){
    System.out.println(Thread.currentThread().getName()+"运行……"+i);
    }
  }
}

public class ThreadJoinDemo {

  public static void main(String[] args) {
    MyThread mt = new MyThread();
    Thread t = new Thread(mt);
    t.start();
    for(int i=0;i<30;i++){
      if(i>10){
        try{
          t.join();
        }catch(Exception e){}
      }
      System.out.println("Main线程"+i);
    }
  }
}

线程的休眠:
sleep为静态方法,使用类名Thread直接调用
class MyThread implements Runnable{
  public void run(){
    for(int i=0;i<5;i++){
      try{
        Thread.sleep(1000);//每次输出都会间隔1000ms,达到延迟操作的结果
      }catch(Exception e){}
      System.out.println(Thread.currentThread().getName()+"…………"+i);
    }
  }
}

public class ThreadSleepDemo {

  public static void main(String[] args) {
    MyThread mt = new MyThread();
    new Thread(mt,"线程").start();
  }

}

线程的中断:
class MyThread implements Runnable{
  public void run(){
    System.out.println("进入run方法");
    try{
      Thread.sleep(10000);
      System.out.println("已完成休眠");
    }catch(Exception e){
    System.out.println("休眠被终止");
    return;
    }
  System.out.println("正常结束");
  }
}

public class ThreadInterruptDemo {
  public static void main(String[] args) {
    MyThread mt = new MyThread();
    Thread t = new Thread(mt);
    t.start();
    try{
      Thread.sleep(2000);
    }catch(Exception e){}
    t.interrupt();
  }
}

在使用join和sleep时,要进行异常处理。

线程的礼让:
class MyThread implements Runnable{
  public void run(){
    for(int i=0;i<5;i++){
      System.out.println(Thread.currentThread().getName()+"运行"+i);
      if(i==2){
        System.out.print("线程礼让:");
        Thread.currentThread().yield();
      }
    }
  }
}

public class ThreadYieldDemo {

  public static void main(String[] args) {
    MyThread mt = new MyThread();
    Thread t1 = new Thread(mt,"线程A");
    Thread t2 = new Thread(mt,"线程B");
    t1.start();
    t2.start();
  }
}

每当线程满足条件(i=2)时,本线程就会停止,而让其他线程先执行。

同步:指多个操作在同一时间段内只能有一个线程进行,其他线程要等待此线程完成之后才可以继续进行。

解决资源共享的同步操作,可以使用同步代码块和同步方法两种方式完成。

同步代码块:
class MyThread implements Runnable{
  private int ticket = 20;
  public void run(){
    for(int i=0;i<100;i++){
      synchronized(this){ //将当前对象(this)设置成同步对象
        if(ticket>0){
          System.out.println(ticket--);
        }
      }
    }
  }
}

public class SynchronizedDemo {

  public static void main(String[] args) {
      MyThread mt = new MyThread();
      new Thread(mt).start();
      new Thread(mt).start();
      new Thread(mt).start();
  }
}

同步方法:(使用synchronized关键字将一个方法声明为同步方法)
class MyThread implements Runnable{
  private int ticket = 50;
  public void run(){
    for(int i=0;i<100;i++){
      this.sale();
    }
  }
  private synchronized void sale() {
    if(ticket>0){
      System.out.println(ticket--);
    }
  }
}

public class SynchronizedDemo {

  public static void main(String[] args) {
    MyThread mt = new MyThread();
    new Thread(mt).start();
    new Thread(mt).start();
    new Thread(mt).start();
  }
}

Java中方法定义的完整格式:
访问权限(public、default、protected、private)[final][static][synchronized]
返回值类型 void 方法名称(参数类型,参数名称)[throws Exception1,Exception2]
{
return 返回值;
}

死锁:指两个线程都在等着彼此先完成,造成了程序的停滞。

卖票:同一个动作处理同一资源

生产者消费者:不同动作处理同一资源
class Info{
  private String name = "zhangsan";
  private String content = "java";
  private boolean flag = false;
  public synchronized void set(String name,String content){
    if(!flag){
      try{
        super.wait();
      }catch(InterruptedException e){
        e.printStackTrace();
      }
    }
    this.name = name;
    this.content = content;
    flag = false;
    super.notify();
  }
  public synchronized void get(){
  if(flag){
    try{
      super.wait();
    }catch(InterruptedException e){
      e.printStackTrace();
    }
  }
  System.out.println(name+":"+content);
  flag = true;
  super.notify();
  }
}

class Producer implements Runnable{
  private Info info = null;
  public Producer(Info info){
    this.info = info;
  }
  public void run(){
  boolean flag = false;
  for(int i=0;i<10;i++){
    if(flag){
      this.info.set("zhangsan", "java");
      flag = false;
    }else{
      this.info.set("wangzhi","www");
      flag = true;
    }
  }
}
}

class Consumer implements Runnable{
  private Info info = null;
  public Consumer(Info info){
    this.info = info;
  }
  public void run(){
    for(int i=0;i<10;i++){
      try{
        Thread.sleep(100);
      }catch(Exception e){
        e.printStackTrace();
      }
      this.info.get();
    }
  }
}

public class ThreadCaseDemo {

  public static void main(String[] args) {
    Info i = new Info();
    Producer pro = new Producer(i);
    Consumer con = new Consumer(i);
    new Thread(pro).start();
    new Thread(con).start();
  }
}

停止线程运行:在多线程开发中可以通过设置标志位的方式停止一个线程的运行。