传智播客——毕向东25--第11天总结-10

来源:互联网 发布:四层别墅网络覆盖方案 编辑:程序博客网 时间:2024/05/01 09:00

多线程
 进程:是一个正在执行的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径或者叫一个控制单元。
 线程:是进程中的一个独立的控制单元。线程在控制着进程的执行
一个进程中至少有一个线程
创建线程
    方式一:继承Thread类,并重写run方法
          a.定义类并继承Thread类;
         b.重写Thread类中的run方法;
         c.调用线程的satrt方法;
   class Demo extends Thread
   {
        public void run()
         {
               for(int x=0;x<60;x++)
              System.out.println("demo run......");
         }
   }
   class ThreadDemo
   {
          public static void main(String[]args)
          {
                Demo d=new Demo();
                d.start();
                for(int x=0;x<60;x++)
                           System.out.println("Hello Word!");
           }
   }
 JVM在启动的时候会有一个进程java.exe,该进程中至少一个线程负责java程序的执行,而且这个线程运行的代码存在于main方法中,该线程称为主线程。

 run和start的特点:
         run()方法:仅是对象调用的方法;
        start()方法:开启线程并执行该线程run方法

例:创建两个线程和主线程交替运行:
     class Test extends Thread
     {
          private String name;
          Test(String name)
             {
                  this.name=name;
              }
          public void run()
           {
               for(int x=0;x<60;x++)
                      System.out.println(name+"run......"+x);
           }
     }
  class ThreadTest
  {
           public static void main(String[] args)
            {
               Test t1=new Test("one");
               Test t2=new Test("two");
                t1.start();
               t2.start();
               for(int x=0;x<60;x++)
                     System.out.println("main......"+x);
            }
  }
获取线程对象以及名称:
     getName():获取线程名称
 线程有自己默认的名称:Thread-编号(编号从0开始)
 
 static Thread currentThread():获取当前线程对象
     例:Thread.currentThread().getName():返回当前对象

售票的例子:继承Thread的方式:
        class Ticket extends Thread
     {
      private static int tick=100;
      public void run()
      {
       while(true)
       {
        if(tikc>0)
         System.out.println(Thread.currentThread().getName()+"...sale:"+tick--);
       }
      }
     }
     class TicketDemo
     {
      public static void main()
      {
       Ticket t1=new Ticket();
       Ticket t2=new Ticket();
       Ticket t3=new Ticket();
       Ticket t4=new Ticket();
       t1.start();
       t2.start();
       t3.start();
       t4.start();
      }
     }

方式二:实现Runable接口:
       步骤:1.定义类实现Runnable接口;
                 2.覆盖Runnable接口中的run方法
                 3.通过Thread类建立线程对象
                 4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
                5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法;
 售票的例子:实现Runnable的方式:
     class Ticket implements Runnable
     {
   private int tick=100;
   public void run()
   {
    while(true)
    {
     if(tick>0)
      System.out.println(Thread.currentThread().getName()+"...sale:"+tick--);
    }
   }
     }
  class TicketDemo
  {
   public static void main(String[] args)
   {
    Ticket t=new Ticket(); //同一个对象
    Thread t1=new Thread(t);
    Thread t2=new Thread(t);
    Thread t3=new Thread(t);
    Thread t4=new Thread(t);
    t1.start();
    t2.start();
    t3.start();
    t4.start();
   }
  }
继承Thread和实现Runnable两种方式的区别:
      继承Thread:线程代码存放Thread子类run()方法中
      实现Runnable:线程代码在接口的子类run()方法中

 多线程的安全问题:
     CPU在进行切换执行时,会使线程停留在一个错误的位置,售票系统会产生票数为负的情况;
 
 解决方法:同步代码块
    语法:synchronized(对象)
    {
     需要同步的代码;
    }
  同步代码块示例:
         :
   :
   :
  while(true)
  {
   synchronized(obj); //Object obj=new Object();
   {
    if(tick>0)
    {
     try{Thread.sleep(10);}
     catch (Exception e){}
     System.out.println(Thread.currentThread().getName()+"...sale:"+tick--);
    }
   }
   
  }
对象如同锁,持有锁的线程可以再同步中执行;

线程同步的前提:
            1.必须要有两个或两个以上的线程
           2.必须是多个线程使用同一个锁


同步函数:
     同步函数:在函数上加入synchronized关键字
  例:public synchronized void add()
     {......}
 示例:有两个储户分别存300元,每次存100,存了3次
    class Bank
    {
     private int sum;
     public synchronized void add(int n)
     {
      sum=sum+n;
      try{Thread.sleep(10);}
      catch(Exception e){}
      System.out.println("sum="+sum);
     }
    }
    class Cus implements Runnable
    {
     private Bank b=new Bank();
     public void run()
     {
      for(int x=0;x<3;x++)
      {
       b.add(100);
      }
     }
    }
    class BankDemo
    {
     public static void main(String[] args)
     {
      Cus c=new Cus();
      Thread t1=new Thread(c);
      Thread t2=new Thread(c);
      t1.start();
      t2.start();
     }
    }
同步函数默认的锁是this:
          .....
    public void run()
    {
     while(true)
     {
      synchronized(this) //this当前同步函数对象
      {... ...}
     }
    }
    public synchronized void show() //同步函数
    {
     ... ...
    }

静态同步函数的锁是class对象:
      静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象:类名.class 该对象类型是class;
      静态的同步方法,使用的锁是该方法所在类的字节码文件对象 类名.class;
   private static int tick=100;
           ......
     synchronized(Ticket.class)    //字节码文件对象
     ......
  class Ticket
  {
         ......
         public static synchronized void show()
      ......
  }

单例设计模式:
    //饿汉式:
          class Single
          {
     private static final Single s=new Single();
     private Single(){}
     public static Single getInstance()
     {return s;}
          }
 //懒汉式:线程同步
          class Single
          {
     private static Single s=null;
     private Single(){}
     public static Single getInstance()
     {
      if(s==null)                        //判断1
      {
       synchronized(single.class)   //字节码文件对象
       {
        if(s==null)                //判断2  双重判断解决低效问题
         //-->A
            //-->B
         s=new Single();
       }
      }
      return s;
     }
          }

多线程-死锁:
             ......
   puclic void run
   {
    if(flag)
    {
     synchronized(MyLock.locka)                //有a锁要b锁
     {
      System.out.println("if locka");     
      synchronized(MyLock.lockb)
      {
       System.out.println("if lockb");
      }
     }
    }
    else
    {
     synchronized(MyLock.lockb)                //有b锁要a锁
     {
      System.out.println("else lockb");
      synchronized(MyLock.locka)
      {
       System.out.println("else locka");
      }
     }
    }
   }
   class MyLock
   {
    static Object locka=new Object();
    static Object lockb=new Object();
   }
   ......

 

 

原创粉丝点击