线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。

  线程的创建

    一:继承Thread类。步骤:

      1,定义类继承Thread。

      2,复写Thread类中的run方法。      目的:将自定义代码存储在run方法。让线程运行。

            class Demo extends Thread
            {
                 public void run()
                 {
                      for(int x=0; x<60; x++)
                           System.out.println("demo run----"+x);
                 }
            }

      3,调用线程的start方法,               该方法两个作用:启动线程,调用run方法。

            

            class ThreadDemo {

                public static void main(String[] args)  {

                     //for(int x=0; x<4000; x++)

                    //System.out.println("Hello World!");

                   Demo d = new Demo();//创建好一个线程。   

                    //d.start();//开启线程并执行该线程的run方法。  

                    d.run();//仅仅是对象调用方法。而线程创建了,并没有运行。

                  for(int x=0; x<60; x++)

                        System.out.println("Hello World!--"+x);

                 }

            }

      线程的运行状态:

          

    二:创建线程的第二种方式:实现Runable接口        

        步骤:

          1,定义类实现Runnable接口

          2,覆盖Runnable接口中的run方法。  将线程要运行的代码存放在该run方法中。

          3,通过Thread类建立线程对象。

          4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

          5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

class Ticket implements Runnable//extends Thread {     

      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();

    }

}

      为什么要将Runnable接口的子类对象传递给Thread的构造函数?
         因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。

      实现方式和继承方式有什么区别呢?

        实现方式好处:避免了单继承的局限性。在定义线程时,建议使用实现方式。

        继承Thread:线程代码存放Thread子类run方法中。

        实现Runnable,线程代码存在接口的子类的run方法。

      获取当前线程对象:static Thread currentThread();

      获取线程名称:getName();

class Test extends Thread {

    Test(String name)  {   //父类有这样的构造方法

      super(name);

    }

    public void run()  {

        for(int x=0; x<60; x++)   {

          System.out.println((Thread.currentThread()==this)+"..."+this.getName()+" run..."+x);

        }

     }

}

class ThreadTest
{
   public static void main(String[] args)
   {
      Test t1 = new Test("one---");
      Test t2 = new Test("two+++");
      t1.start();
      t2.start();

  }

}

    多线程的安全问题:通过分析,发现,打印出0,-1,-2等错票。问题的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执

行完,另一个线程参与进来执行。导致共享数据的错误。解决办法:对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。这就出来了

同步代码块

synchronized(对象) {  

    需要被同步的代码

}

    对象如同锁。持有锁的线程可以在同步中执行。 没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

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

    好处:解决了多线程的安全问题。

    弊端:多个线程需要判断锁,较为消耗资源。

class Ticket implements Runnable {

     private  int tick = 1000;

    Object obj = new Object();  

    public void run()  {

        while(true)   {

          synchronized(obj)    {

            if(tick>0)     {

                //try{Thread.sleep(10);}catch(Exception e){}

                 System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);

             }

          }

        }

     }

}

class  TicketDemo2 {

      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();

      }

}

      同步函数:同步代码块用来封装代码的,函数也是来封装代码的,我们试图让函数具备同步性,也可以达到相同的效果。   

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:如果直接将synchronized关键字放到run() 函数上做成同步函数,发现效果不行 ,应为只启动了0号线程,分析后得知,是同步的代码没弄清楚,后来将同步代码部分提取后,封装成独立的show()函数调用并同步synchronized,就可以了。这个时候问一个问题,它的锁是什么呢?函数需要被对象调用,函数都有一个所属对象的引用时this所以同步函数的锁对象是this。为了验证,使用两个线程买票,一个线程在同步代码快中,一个在同步函数中,都在执行买票动作,如果要是同步就不会出现错误的票。

class Ticket implements Runnable {

    private  int tick = 100;

    //Object obj = new Object();

    boolean flag = true;

    public  void run()  {

        if(flag)   {

            while(true)    {

                //synchronized(this)     {

                    if(tick>0)      {

                         try{Thread.sleep(10);}catch(Exception e){}

                         System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);

                    }

                }

             }

         }

          else

            while(true)

                show();

    }

     public synchronized void show()//this

    {

        if(tick>0)   {

           try{Thread.sleep(10);}catch(Exception e){}

          System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);

        }

    }

}

class  ThisLockDemo {

     public static void main(String[] args)  {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);

          Thread t2 = new Thread(t);

          t1.start();

          try{

            Thread.sleep(10);

         }catch(Exception e){}

         t.flag = false;

        t2.start();
     }
}

    函数被静态修饰后,使用的锁是:类名.class

class Ticket implements Runnable {

    private static  int tick = 100;

    //Object obj = new Object();

     boolean flag = true;

    public  void run()  {

      if(flag)   {

           while(true)    {

              synchronized(Ticket.class)     {

                   if(tick>0)      {

                      try{Thread.sleep(10);}catch(Exception e){}

                      System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);

                   }

              }

           }

       }

       else

          while(true)

              show();

    }

    public static synchronized void show()  {

          if(tick>0)   {

              try{Thread.sleep(10);}catch(Exception e){}

              System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);

          }

    }

}

class  StaticMethodDemo {

     public static void main(String[] args)  {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);

          Thread t2 = new Thread(t);

          t1.start();

          try{Thread.sleep(10);}catch(Exception e){}

          t.flag = false;

          t2.start();

     }

}

单例设计模式

懒汉式:

class Single {

    private static Single s = null;

    private Single(){}

    public static  Single getInstance()  {

        if(s==null)   {

            synchronized(Single.class)    {

                if(s==null)

                //--->A;

                s = new Single();

            }

        }

        return s;

     }

}

class SingleDemo {

    public static void main(String[] args)  {

        System.out.println("Hello World!");

    }

}

    死锁:

class Test implements Runnable {

    private boolean flag;

    Test(boolean flag)  {

        this.flag = flag;

    }

    public void run()  {

        if(flag)   {

            while(true)    {

                synchronized(MyLock.locka)     {

                      System.out.println(Thread.currentThread().getName()+"...if locka ");

                      synchronized(MyLock.lockb)      {

                          System.out.println(Thread.currentThread().getName()+"..if lockb");

                      }

                }

            }

        }

        else   {

            while(true)    {       

                synchronized(MyLock.lockb)     {

                      System.out.println(Thread.currentThread().getName()+"..else lockb");

                      synchronized(MyLock.locka)      {

                          System.out.println(Thread.currentThread().getName()+".....else locka");

                }

            }

        }

    }

  }

}

class MyLock {

    static Object locka = new Object();

    static Object lockb = new Object();

}

class  DeadLockTest {

    public static void main(String[] args)  {

        Thread t1 = new Thread(new Test(true));

        Thread t2 = new Thread(new Test(false));

        t1.start();

        t2.start();

    }

}

转载于:https://www.cnblogs.com/zhaolibin198627/archive/2013/05/24/3097980.html

黑马程序员---java基础------------------多线程相关推荐

  1. 黑马程序员——java基础---多线程(二)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! -------  线程间的通信:简单来说,就是多个线程在操作同一资源,但操作的动作不同. 试想一下,对于同一个资 ...

  2. 黑马程序员——Java基础---多线程

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 多线程 一.概述 说起多线程,我们就需要首先来谈谈什么叫做进程.所谓进程,就是在计算机上正在进行 ...

  3. 黑马程序员JAVA基础-多线程

    ------- android培训.java培训.期待与您交流! ---------- 线程: 线程是进程中的一个独立的控制单元 线程在控制着进程的执行 一个进程中至少有一个线程 线程的创建 第一种方 ...

  4. 黑马 程序员——Java基础---流程控制

    黑马程序员--Java基础---流程控制 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java提供了两种基本的流程控制结构:分支结构 ...

  5. 黑马 程序员——Java基础---IO(下)

    黑马程序员--Java基础---IO(下) ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供 ...

  6. 黑马程序员-Java基础:面向对象(上)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.面向对象概述 当需求单一,或者简单时,我们一步一步去操作没问题,并且效率也挺高.可随着需求的 ...

  7. 黑马程序员——java的多线程

    ------- android培训.java培训.期待与您交流! ---------- 前言:通过观看毕向东老师的java基础视频,查漏补缺,将一些自己掌握的还不牢固的知识写出来,希望和大家交流分享. ...

  8. 黑马程序员--Java基础加强篇

    开发工具使用 --------------------------------------------------------------------------------------------- ...

  9. 黑马程序员-Java基础:设计模式总结

    --Java培训.Android培训.iOS培训..Net培训.期待与您交流! -- Java基础部分设计模式 一.设计模式概述 设计模式(Design pattern)是一套被反复使用.多数人知晓的 ...

最新文章

  1. 效率提升看得见 神策 A/B 测试可视化试验能力正式上线
  2. 奇怪的吃播_吃播,我看吐了!
  3. Expression Blend实例中文教程(4) - 布局控件快速入门Canvas
  4. warning no newline at the end of file
  5. 项目一计算机基础知识考核题,2013计算机基础知识试题及答案
  6. thinkpad t460p恢复原厂系统以及设置的方式
  7. git 修改远程仓库地址
  8. R中读取文件,找不到路径问题 No such file or directory
  9. 最新PHP乐购社区源码+点卡购物系统
  10. radius服务器搭建
  11. QPainter画箭头
  12. 【Linux系统】第2节 虚拟机中安装Kali系统
  13. 显著性水平和p值的理解
  14. Android:手机号码归属地查询
  15. 牛腩新闻发布--触发器语句
  16. .com与.top域名有什么区别
  17. Android 科大讯飞语音评测SDK 踩坑实录
  18. python有趣小程序春节祝福-用python实现新年祝福微信的自动回复
  19. 在Keras的Embedding层中使用预训练的word2vec词向量
  20. 金蝶kis记账王怎么反审核凭证

热门文章

  1. BZOJ 1085(IDA*)
  2. HDU 1542:Atlantis(扫描线+线段树 矩形面积并)***
  3. 一个渣渣的随页面滚动改变定位的代码
  4. mysql颠覆实战笔记(五)--商品系统设计(二):定时更新商品总点击量
  5. vivo真实案例:中台到底解决了什么问题?
  6. 2021年,AI哪个方向最火?看看大神们怎么说
  7. 数据科学、人工智能TED演讲TOP 10
  8. LwIP之动态内存堆
  9. Objects.equals 有坑!!!
  10. 程序员必备的GitHub加速指南,真香!