黑马程序员_java之多线程

------- android培训java培训、期待与您交流! ----------
 

多线程:


 1、多线程
       进程:正在运行的程序叫进程
       线程:进程在执行过程中,可能需要多个任务同时执行,每个任务的执行者就是线程
 2、jvm启动是多线程
 3、如何实现多线程
     
A:继承Thread类
     步骤:
     定义一个类,继承Thread类
     重写run方法
     调用start方法.
     启动线程
     调用run方法
  
   
   Thread类中的常用方法:
          1、Thread(String name):通过构造给线程起名字
          2、setName(String name):通过set方法给线程起名字
          3、getName():获取线程的名称
          4、currentThread():获取当前线程的一个对象引用
          5、获取那些没有直接继续Thread类的线程名称

      B:实现Runnable接口
      步骤:
      定义一个类,实现Runnable接口
      重写run方法
      创建实现了Runnable接口的子类对象,并把该对象作为参数传递给
      Thread类的对象.这个时候,调用Thread类的start方法.
 4、线程的生命周期
      A:创建
      B:就绪
      C:运行
      D:阻塞 sleep,wait导致阻塞,sleep的时间到了,wait的被唤醒了.就到了就绪状态
      E:死亡
5、卖票的问题
      A:继承Thread实现卖票,这个时候,我们的票需要定义为静态的.但是呢,我们不建议这样做.
      B:实现Runnable接口卖票,在这里,发现卖票出了问题.(线程安全问题)

6、线程安全问题的产生:
          多个线程延迟访问
          线程的随机性
7、解决线程安全问题
      A:同步代码块
          格式: synchronized(对象)
         {
              //被同步的代码,也就是可能出现安全问题的代码
         }
      B:同步方法
         就是在方法上加synchronized关键字即可.
      C:同步的前提:
         同步需要两个或者两个以上的线程
         多个线程使用的是同一个锁。
         未满足这两个条件,不能称其为同步。
      D:同步的弊端:
         当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,
         无形中会降低程序的运行效率。

        同步可能造成死锁问题:
        死锁的产生:
        你拿着我们的锁,我拿着你的锁,谁都不先对方用.

        针对程序来说,就是我想用你的锁,而你也想用我的锁.都不放手.导致了死锁.

单例的安全问题:


class Student
{
 private Student(){}

 private static Student s = null;

 public static Student getInstance()
 {
  if(s==null)  //t1,t2,t3,t4
  {
   //如果进来了就创建了多个对象.不满足单例的要求.
   s = new Student();
  }
  return s;
 }
}
//采用双重判断解决该问题
 If(instance == null) {
 synchronized(Single.class) {
  if(instance == null) {
   instance = new Single();
  }
 }
}
return instance;

线程间的通信:
1、以前操作一个资源的时候,用的是同一种类型的线程来进行多线程的操作.
       现在,我们对一个资源的操作,用不同种类型的线程来操作,这不同类型间的线程是有关系的.
       这就称作线程间的通信.
    举例:
      我们既可以从自己的卡里取钱,也可以往卡里存钱.
2、资源:可能是一个基本数据类型,也可能是一个引用类型.还可能是一个大的容器.
3、我们有一个学生资源,我们可以输出学生,也可以设置学生信息.
       并且,你可以多次输出学生信息,也可以多次设置学生信息.
       用此例模拟线程间的通信.

    重点.

   public class Student
   {
  String name;
  int age;
   }

    //设置值
    public class Input implements Runnable
    {
  private Student s;

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

  public void run()
  {
   //设置值
   int x = 0;

   while(true)
   {
    synchronized(s)
    {
     if(x%2==0)
     {
      s.name = "张三";
      s.age = 40;
     }
     else
     {
      s.name = "李四";
      s.age = 30;
     }
    }
    x++;
     }
   }
 }


    //获取值
    public class Output implements Runnable
    {
  private Student s;

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

  public void run()
  {
   //获取值
   while(true)
   { 
    synchronized(s)
    {
     System.out.println(s.name+"***"+s.age);
    }
    
       }
     }
  }
 
    //测试类
    public class StudentTest
    {
  public static void main(String[] args)
  {
   Studnet s = new Student();

   Input in = new Input(s);
   Output out = new Output(s);

   Thread t1 = new Thread(in);
   Thread t2 = new Thread(out);

   t1.start();
   t2.start();
   }

 }

  这样就解决了线程间通信的安全问题.

 

4、解决数据一个的互相输出问题

 wait:让线程等待
 notify:唤醒线程池中的第一个线程
 notifyAll:唤醒线程池中的所有线程
5、为什么这些方法定义在了Object类中.
      A,这些方法存在与同步中。
      B,使用这些方法时必须要标识所属的同步的锁。
      C,锁可以是任意对象,所以任意对象调用的方法一定定义Object类中。


6、wait()和sleep()的区别:
      A:wait()可有无参数的调用.
          而sleep必须指定睡眠时间.但是有些时候,睡眠时间不好确定.这个时候就可以使用wait.
      B:wait:释放了执行权,释放锁.
         sleep:释放了执行权,不释放锁.
         sleep有醒过来的时候,而wait可能醒不了.
7、停止线程的方式:
         A:通过stop方法停止线程.但是这个方法过时,所以不推荐使用.使用 interrupt方法来中断该等待
         B:线程中的代码一般都是在循环中的.可以通过控制循环的次数来让run方法结束.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值