黑马程序员 JAVA基础 多线程

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

 

1:多线程
 (1)线程:线程是进行的执行单元,执行路径。
  进程:就是正在运行的程序。一块正在被使用的内存区域。
  如果一个应用程序的执行只有一条执行路径,被称为单线程程序。
  如果一个应用程序的执行有多条执行路径,被称为多线程程序。
  
  举例:
   迅雷下载,360管理界面,班长请吃饭,去医院体检
 (2)JVM的启动是多线程的吗?
  是。因为如果JVM启动只启动了main线程的话,那么,在程序的执行过程中,
  有可能会引发内存溢出,而java很少看到这种情况,为什么呢,就是因为,
  java的垃圾回收线程一直也在运行,当内存不够的情况,会自动去扫描内存中
  是否有垃圾存在,有就立马清除。
  这样来说,最低有两个线程启动了。所以,JVM的启动是多线程的。
 (3)自己如何模拟多线程程序
  
A:继承Thread类
   步骤:
    a:创建一个类,继承Thread类
    b:重写run方法
    c:创建类对象,调用start方法

   代码体现:
    
   
 public class ThreadDemo extends Thread
    {
     @Override
     public void run()
     {
      for(int x=0; x<100; x++)
      {
       System.out.println(getName()+"***"+x);
      }
     }
    }

    public class ThreadDemoTest
    {
     public static void main(String[] args)
     {
      ThreadDemo td1 = new ThreadDemo("刘备");
      ThreadDemo td2 = new ThreadDemo("孙权");

      td1.start();
      td2.start();
     }
    }

  B:实现Runnable接口
   步骤:
    a:创建一个类,实现Runnable接口
    b:重写run方法
    c:创建Thread类对象,创建Runnable子类对象,把Runnable的子类
      对象作为构造参数传递给Thread的构造方法
    d:调用start方法  
    
   代码体现:
    
   
 public class RunnableDemo implements Runnable
    {
     @Override
     public void run()
     {
      for(int x=0; x<100; x++)
      {
       System.out.println(Thread.currentThread().getName()+"***"+x);
      }
     }
    }

    public class ThreadDemoTest
    {
     public static void main(String[] args)
     {
      RunnableDemo rd = new RunnableDemo();

      Thread td1 = new Thread(rd,"林青霞");
      Thread td2 = new Thread(rd,"刘意");

      td1.start();
    
  td2.start();
     }
    }
 (4)实现多线程的方式有几种,分别怎么实现?
 (5)启动线程调用的是哪个方法,它做了什么事情?
  启动线程调用的是start()方法。
  它启动线程,并且自动调用了run()方法。

  start()和run()的区别?
 (6)线程的生命周期及每个状态的特点。
  新建:创建线程对象
  就绪:具有执行资格,没有执行权
  运行:具有执行资格,有执行权
   阻塞:没有执行资格,没有执行权
  死亡:对象变成垃圾

内存体现:

黑马程序员  JAVA基础三 多线程 - 619294300 - 619294300的博客

 

  
 (7)下午通过卖票程序演示出线程安全问题。
  A:线程安全是怎么产生的?
   线程的随机性
   线程的延迟性
  B:如何判断某段代码有没有线程安全问题呢?
   a:有没有共享数据
   b:看是否有多条语句操作共享数据
   c:看是否有多个线程进行操作
  c:如何解决线程安全问题?
   a:同步代码块
    synchronized(对象)
    {
     需要被同步的代码。
    }

    对象:可以是任意对象。
   b:同步方法
    在方法上添加synchronized关键字即可

    锁对象:this

    注意:静态方法的锁对象 当前类的字节码文件对象。
          类名.class
  D:同步前提
   a:两个以上的线程操作的时候
   b:对这多个线程加同步必须使用的是同一把锁
  E:同步弊端
   每次程序的执行都会去判断锁对象,消耗了资源,降低了效率。

   线程安全,效率低。
   线程不安全,效率高。

   开发中的一个难题:要么效率,要么安全。
 (8)卖票程序
  public class Ticket implements Runnable
  {
   //定义100张票
  
 private int tickets = 100;
  
   @Override
   public void run()
   {
    while(true)
    {
     synchronized(this){
      if(tickets>0)
      {
       try{
        Thread.sleep(10);
       }catch(InterruptedException e){
        e.printStackTrace();
       }
       System.out.println(Thread.currentThread().getName()+"正在卖出第"+(tickets--)+"张票");
      }
     }
    }
   }
  }

  public class Test
 
 {
   public static void main(String[] args)
   {
    Ticket t = new Ticket();

    Thread t1 = new Thread(t,"窗口1");
    Thread t2 = new Thread(t,"窗口2");
    Thread t3 = new Thread(t,"窗口3");
    Thread t4 = new Thread(t,"窗口4");
    
    t1.start();
    t2.start();
    t3.start();
    t4.start();
   }
  }
 (9)单例设计模式的懒汉式,请问他有没有线程安全问题

  public class Student
  {
   private Student(){}

   private static Student s = null;

   public synchronized static Student getStudent()
   {
    //t1,t2,t3
    if(s==null) 
    {
     //t1,t2,t3
     s = new Student();

     //t1线程首先创建了一个对象
     //t2线程继续创建了一个对象
     //t3线程又创建了一个对象
    }
    return s;
   }
  }

  A:延迟加载
  B:线程安全问题


  //开发中,用饿汉式即可。
  public class Student
  {
   private Student(){}

   private static Student s = new Student();

   public static Student getStudent()
   {
    return s;
   }
  }

线程范围内的共享数据:在同一个线程数据共享,但在不同线程,数据不共享。

代码体现:

private static int date = 0;//共享数据
 
public static void main(String[] args) {
          for( int i=0;i<=1;i++){
           new Thread(new Runnable(){
              @Override 

public void run() {
     date = new Random().nextInt();
     System.out.println("***"+Thread.currentThread().getName()+"***"+date);
     new A().get();
     new B().get();
    }
   }).start(); 
   
   
  }
 }
 static class A{
  public void get(){
   System.out.println("A***"+Thread.currentThread().getName()+"***"+date);
  }
 }
 static class B{
 
 public void get(){
   System.out.println("B***"+Thread.currentThread().getName()+"***"+date);
  }
 }
 
}

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章