多线程

多线程

  进程:正在运行的程序。

  线程:进程的一个执行单元,一条路径
   
  1.1 多线程的创建

  线程是程序中的执行线程。Java虚拟机允许应用程序并发地运行多个执行线程

  1.1.1 方式1

  将类申明为java.lang包下Thread的子类,该子类重写Thread类的run方法,实例化子类对象并启动线程

    public final String getName()    返回该线程的名称

    public final void setName(String name)    设置线程的名称   

  1.1.2 方法2

   声明实现java.lang包下Runnable接口的类,该类重写run方法,实例化该类对象,在创建Thread对象时作为一个参数进行传递并启动

  public static Thread currentThread()  返回当前正在执行线程的对象引用

  1.1.3 继承Thread类与实现Runnable接口方式的区别
  
    避免单继承的局限性;实现接口方式,只创建了一个资源对象,更好地实现了数据和操作的分离。一般选择实现接口的方式创建多线程
  
  1.2 线程的生命周期
  
  新建状态---------就绪状态---------阻塞状态()---------运行状态---------死亡状态

  
   线程的创建(两种方式:一个类继承Thread类,一个类实现Runnable接口)
继承Thread类方式:
public class MyThread extends Thread {
 @Override
 public void run() {
  for(int x=0;x<10;x++){
   System.out.println(getName()+"---hello"+x);
  }
 }
}
public class ThreadTest {
 public static void main(String[] args) {
  //创建多线程对象
  MyThread mt1 = new MyThread();
  MyThread mt2 = new MyThread();
  
  //设置线程名称
  mt1.setName("Nina");
  mt2.setName("Lucy");
  //启动线程
  mt1.start();
  mt2.start();
 }
}
实现Runnable接口方式:
public class MyRunnable implements Runnable{
 @Override
 public void run() {
  for(int x=1;x<11;x++){
   System.out.println(Thread.currentThread().getName()+"---hello"+x);
  }
 }
}
public class MyRunnableTest {
 public static void main(String[] args) {
  MyRunnable mr = new MyRunnable();
  Thread t1 = new Thread(mr);
  Thread t2 = new Thread(mr);
  t1.setName("中国地");
  t2.setName("闯关东");
  t1.start();
  t2.start();
 }
}
   两种方式下的火车站窗口出售火车票
继承Thread类方式:
public class TicketThread extends Thread{
 //票资源
 private static int tickets = 20;
 @Override
 public void run() {
  while(true){
   if(tickets>0){
    System.out.println(getName()+"正在出售第"+tickets--+"张票");
   }
  }
 }
}
public class ThreadTest {
 public static void main(String[] args) {
  //创建四个窗口--启动四个线程
  TicketThread tt1 = new TicketThread();
  TicketThread tt2 = new TicketThread();
  TicketThread tt3 = new TicketThread();
  TicketThread tt4 = new TicketThread();
  //设置线程名称
  tt1.setName("窗口1");
  tt2.setName("窗口2");
  tt3.setName("窗口3");
  tt4.setName("窗口4");
  //启动线程
  tt1.start();
  tt2.start();
  tt3.start();
  tt4.start();
 }

实现Runnable方式:
public class TicketsRunnable implements Runnable{
 private int tickets =20;
 public void run() {
  while(true){
   if(tickets>0){
    System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets--+"张票");
   }
  }
 }
}
public class TicketThreadTest {
 public static void main(String[] args) {
  TicketsRunnable tr = new TicketsRunnable();
  Thread t1 = new Thread(tr);
  Thread t2 = new Thread(tr);
  Thread t3 = new Thread(tr);
  Thread t4 = new Thread(tr);
  t1.setName("窗口1");
  t2.setName("窗口2");
  t3.setName("窗口3");
  t4.setName("窗口4");
  t1.start();
  t2.start();
  t3.start();
  t4.start();
 }
}
   实现Runnable接口方式下加入Thread.sleep(100)操作语句,出现的问题:相同票数、0票和负数票
public class TicketsRunnable implements Runnable {
 private int tickets =100;
 @Override
 public void run() {
  while(true){
   if(tickets>0){
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets--+"张票");
   }
  }
 }
}
public class RunnableTest {
 public static void main(String[] args) {
  TicketsRunnable tr = new TicketsRunnable();
  
  Thread t1 = new Thread(tr);
  Thread t2 = new Thread(tr);
  Thread t3 = new Thread(tr);
  Thread t4 = new Thread(tr);
  
  t1.setName("窗口1");
  t2.setName("窗口2");
  t3.setName("窗口3");
  t4.setName("窗口4");
  
  t1.start();
  t2.start();
  t3.start();
  t4.start();
 }
}

   线程出问题的判断条件:有没有共享资源,对共享资源的操作是否有多条语句,是不是在多线程中
           
   解决方案:同步代码块(同步机制) 锁对象:任意锁对象(同一把锁)(synchronized(锁对象){有问题的代码})
public class TicketsRunnable implements Runnable {
 private int tickets = 100;
 private Object obj = new Object();
 @Override
 public void run() {
  while (true) {
   // 同步机制
   synchronized (obj) {
    if (tickets > 0) {
     try {
      Thread.sleep(100);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     System.out.println(Thread.currentThread().getName()
       + "正在出售第" + tickets-- + "张票");
    }
   }
  }
 }
}
public class RunnableTest {
 public static void main(String[] args) {
  TicketsRunnable tr = new  TicketsRunnable();
  
  Thread t1 = new Thread(tr);
  Thread t2 = new Thread(tr);
  Thread t3 = new Thread(tr);
  Thread t4 = new Thread(tr);
  
  t1.setName("窗口1");
  t2.setName("窗口2");
  t3.setName("窗口3");
  t4.setName("窗口4");
  
  t1.start();
  t2.start();
  t3.start();
  t4.start();
 }
}
             同步方法  锁对象:this对象(把synchronized加在方法上)
public class TicketsRunnable implements Runnable {
 private int tickets =100;
 @Override
 public void run() {
  int x = 0;
  while (true) {
   if (x % 2 == 0) {
     synchronized (this) {
     if (tickets > 0) {
      try {
       Thread.sleep(100);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName()
        + "正在出售第" + tickets-- + "张票");
     }
    }
   }else{
    check();
   }
  }
 }
 //方法,锁加在方法上
 private synchronized void check(){
   if (tickets > 0) {
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()
      + "正在出售第" + tickets-- + "张票");
   }
 }
}
public class RunnableTest {
 public static void main(String[] args) {
  TicketsRunnable tr = new TicketsRunnable();
  
  Thread t1 = new Thread(tr);
  Thread t2 = new Thread(tr);
  Thread t3 = new Thread(tr);
  Thread t4 = new Thread(tr);
  
  t1.setName("窗口1");
  t2.setName("窗口2");
  t3.setName("窗口3");
  t4.setName("窗口4");
  
  t1.start();
  t2.start();
  t3.start();
  t4.start();
 }
}


             静态同步方法  锁对象:类名.class-- Class文件对象
public class TicketsRunnable implements Runnable {
 private static int tickets = 100;
 @Override
 public void run() {
  int x = 0;
  while (true) {
   if (x % 2 == 0) {
     synchronized (TicketsRunnable.class) {
     if (tickets > 0) {
      try {
       Thread.sleep(100);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName()
        + "正在出售第" + tickets-- + "张票");
     }
    }
   }else{
    check();
   }
  }
 }
 //方法,锁加在方法上
 private static synchronized void check() {
   if (tickets > 0) {
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()
      + "正在出售第" + tickets-- + "张票");
   }
 }
}
public class RunnableTest {
 public static void main(String[] args) {
  TicketsRunnable tr = new TicketsRunnable();
  
  Thread t1 = new Thread(tr);
  Thread t2 = new Thread(tr);
  Thread t3 = new Thread(tr);
  Thread t4 = new Thread(tr);
  
  t1.setName("窗口1");
  t2.setName("窗口2");
  t3.setName("窗口3");
  t4.setName("窗口4");
  
  t1.start();
  t2.start();
  t3.start();
  t4.start();
 }
}
  死锁问题
用实现Runable接口方式实现:
public class DeadLockThread implements Runnable {
 private boolean flag;

 public DeadLockThread(boolean flag) {
  this.flag = flag;
 }
 //被static修饰的内容被所有对象共享
 private static Object objA = new Object();
 private static Object objB = new Object();

 @Override
 public void run() {
  if (flag) {
   while (true) {
    synchronized (objA) {
     // dt1进来了
     System.out.println(Thread.currentThread().getName()
       + "--if--objA");
     synchronized (objB) {
      System.out.println(Thread.currentThread().getName()
        + "--if--objB");
     }
    }
   }
  } else {
   while (true) {
    synchronized (objB) {
     // dt2进来了
     System.out.println(Thread.currentThread().getName()
       + "--else--objB");
     synchronized (objA) {
      System.out.println(Thread.currentThread().getName()
        + "--else--objA");
     }
    }
   }
  }
 }
}
public class DeadLockThreadTest {
 public static void main(String[] args) {
  DeadLockThread dt1 = new DeadLockThread(true);
  DeadLockThread dt2 = new DeadLockThread(false);
  
  Thread t1 = new Thread(dt1);
  Thread t2 = new Thread(dt2);
  
  t1.setName("小乔");
  t2.setName("范明");
  
  t1.start();
  t2.start();
  
 }
}
用继承Thread类方式实现:
public class MyLock {
 public static final Object objA =new Object();
 public static final Object objB = new Object();
}
public class DeadLock extends Thread{
 private boolean flag;
 public DeadLock(boolean flag){
  this.flag = flag;
 }
 @Override
 public void run() {
  if(flag){
   while(true){
    synchronized(MyLock.objA){
     System.out.println(Thread.currentThread().getName()+"--if--objA");
     synchronized(MyLock.objB){
      System.out.println(Thread.currentThread().getName()+"--if--objB");
     }
    }
   }
  }else{
   while(true){
    synchronized(MyLock.objB){
     System.out.println(Thread.currentThread().getName()+"--else--objB");
     synchronized(MyLock.objA){
      System.out.println(Thread.currentThread().getName()+"--else--objA");
     }
    }
   }
  }
  }
}
public class DeadLockTest {
 public static void main(String[] args) {
  DeadLock d1 = new DeadLock(true);
  DeadLock d2 = new DeadLock(false);
  d1.setName("小乔");
  d1.setName("范明");
  
  d1.start();
  d2.start();
 }
}
   线程间的通信问题
public class Student {
 //这里不能加private修饰符,private修饰符只能在本类中使用
 String name;
 int age;
}
//创建多线程
public class SetStudent implements Runnable {
 private Student s;

 public SetStudent(Student s) {
  this.s = s;
 }

 // 设置学生属性
 @Override
 public void run() {
  int x = 0;
  while (true) {
   if (x % 2 == 0) {
    s.name="小乔";
    s.age=18;
   }else{
    s.name="范明";
    s.age =26;
   }
   x++;
  }
 }
}
//创建多线程
public class GetStudent implements Runnable {
 private Student s;
 public GetStudent(Student s){
  this.s =s;
 }
 @Override
 public void run() {
  while(true){
   System.out.println(s.name+"***"+s.age);
  }
 }
}
public class StudentTest {
 public static void main(String[] args) {
  Student s = new Student();
  SetStudent ss = new SetStudent(s);
  GetStudent gs = new GetStudent(s);
  
  Thread  t1 = new Thread(ss);
  Thread t2 = new Thread(gs);
  
  t1.start();
  t2.start();
 }
}
由于线程的随机性产生的问题。
判断线程是否出现问题的依据:
   A:是否有共享数据
   B:是否有多条语句操作共享数据
  C:是否在多线程环境中
 
解决方法: 
  用同步解决。
    加入同步代码块解决通信问题
public class Student {
 String name;
 int age;
}
public class SetStudent implements Runnable {
 private Student s;

 public SetStudent(Student s) {
  this.s = s;
 }

 @Override
 public void run() {
  int x=0;
  while(true){
   //使用同步(同步代码块,锁对象为同一把锁)
   synchronized(s){
   if(x%2==0){
    s.name = "小乔";
    s.age =18;
   }else{
    s.name ="范明";
    s.age =26;
   }
   x++;
   }
  }
 }
}
public class GetStudent implements Runnable{
 private Student s;
 public GetStudent(Student s){
  this.s =s;
 }
 @Override
 public void run() {
  while(true){
   synchronized(s){
   System.out.println(s.name+"***"+s.age);
   }
  }
 }
}
public class GetStudent implements Runnable{
 private Student s;
 public GetStudent(Student s){
  this.s =s;
 }
 @Override
 public void run() {
  while(true){
   synchronized(s){
   System.out.println(s.name+"***"+s.age);
   }
  }
 }
}
public class StudentTest {
 public static void main(String[] args) {
  Student s = new Student();
  SetStudent ss = new SetStudent(s);
  GetStudent gs = new GetStudent(s);
  Thread t1 = new Thread(ss);
  Thread t2 = new Thread(gs);
  t1.start();
  t2.start();
 }
}
   11 等待唤醒机制解决线程通信问题
public final void wait():线程等待
public final void notify():唤醒线程
public class Student {
 String name;
 int age;
 //flag作为数据标识,true表示有数据,false表示没有数据
 boolean flag=false;
}
public class SetStudent implements Runnable {
 private Student s;

 public SetStudent(Student s) {
  this.s = s;
 }
 @Override
 public void run() {
  int x = 0;
  while (true) {
   synchronized (s) {
    //没有数据,等待设置数据
    if (s.flag) {
     try {
      s.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     if (x % 2 == 0) {
      s.name = "小乔";
      s.age = 18;
     } else {
      s.name = "范明";
      s.age = 26;
     }
     x++;
    }
    s.flag =true;
    s.notify();
   }
  }
 }
}
public class GetStudent implements Runnable {
 private Student s;
 public GetStudent(Student s) {
  this.s = s;
 }
 @Override
 public void run() {
  while (true) {
   synchronized (s) {
    //没有数据,等待设置获取
    if (!s.flag) {
     try {
      s.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     System.out.println(s.name + "****" + s.age);
    }
    s.flag = false;
    s.notify();
   }
  }
 }
}
public class StudentTest {
 public static void main(String[] args) {
  Student s = new Student();
  GetStudent ss = new GetStudent(s);
  SetStudent gs = new SetStudent(s);
  Thread t1 = new Thread(ss);
  Thread t2 = new Thread(gs);
  t1.start();
  t2.start();
 }
}
加入同步方法解决通信问题
public class Student {
 String name;
 int age;
 boolean flag = false;
 //设置属性方法
 public synchronized void set(String name,int age){
  //没有数据,等待设置
  if(this.flag){
   try {
    this.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   this.name =name;
   this.age =age;
  }
  //修改标记
  this.flag =true;
  this.notify();
 }
 //获取属性方法
 public synchronized void get(){
  if(!this.flag){
   try {
    this.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.out.println(this.name+"****"+this.age);
  }
  //修改标记
  this.flag =false;
  this.notify();
 }
}
public class SetStudent implements Runnable{
 private Student s;
 public SetStudent(Student s){
  this.s = s;
 }
 @Override
 public void run() {
  int x=0;
  while(true){
   if(x%2==0){
    s.set("小乔",18);
   }else{
    s.set("范明", 26);
   }
   x++;
  }
 }
}
public class GetStudent implements Runnable {
 private Student s;
 public GetStudent(Student s){
  this.s = s;
 }
 @Override
 public void run() {
  while(true){
   s.get();
  }
 }
}
public class StudentTest {
 public static void main(String[] args) {
  Student s = new Student();
  SetStudent ss = new SetStudent(s);
  GetStudent gs = new GetStudent(s);
  
  Thread  t1 = new Thread(ss);
  Thread t2 = new Thread(gs);
  t1.start();
  t2.start();
 }
}
守护线程:
public final void setDaemon(boolean on):设置线程为守护线程,一旦前台线程(主线程)结束,守护线程就结束。
插入线程:
public final void join();一旦有join()线程,那么,当前线程必须等待,直到该线程结束。
线程的优先级(线程默认优先级是5,范围为1-10):
public final int getPriority():获取线程的优先级
public final void setPriority(int newPriority):更改线程的优先级
线程让步:
public final void yield():暂停当前正在执行的线程对象,并执行其他线程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值