Github代码地址

多线程

package cn.bdqn.test;
/**
 * 
 * 进程:  应用程序的执行实例!有自己独立的内存空间和系统资源!
 *     是由一个或者多个线程构成! cpu上真正执行的是线程!
 *    比喻:
 *      我们电脑上运行QQ!   QQ程序启动后在电脑就是一个 进程!
 *      QQ可以有多个对话框!每一个对话框,我们就可以理解成一个线程!
 * 线程: CPU调度和分派的基本单位!
 *   
 * 多线程:   
 *      如果在一个进程中,同时运行多个线程,来完成不同的工作,我们称之为  多线程!   
 *      难道是cpu上同时执行多个线程吗?  不是!
 *      多个线程是交替占用CPU资源!并不是真正的同时执行!

* 例子:
* 01. 现在地铁有5个进站口! 有5个人 可以 同时(看着想同时)进站!
* 02. 现在地铁有1个进站口! 有5个人 必须 排队 进站!
* 问题?
* 哪个效率高? 01效率高!
*
* 地铁 : CPU
* 进站口:线程


 *   多线程的好处:
 *      01.充分利用CPU的资源
 *      02.给用户带来更好的体验
 *   
 */
public class MyThread {
    
    //主线程的入口!
    public static void main(String[] args) {
        //获取当前执行的线程
        Thread t = Thread.currentThread();
        System.out.println("当前线程的名称是:"+t.getName());
        //更改线程的名称
        t.setName("主线程");
        System.out.println("当前线程的名称是:"+t.getName());
        
    }
}

 

 


/**
 * 
 * @author 小豆腐
 * 
 *实现多线程的方法:                    
 *  01.继承Thread类!重写run();    
 *  02.实现Runnable接口!重写 run();
 *  
 *  
 * 并发:
 *    在操作系统系统中,在一个时间段中 有多个程序都处于已启动到运行完毕之间,并且这几个程序都处于一个处理器中运行,
 *    则在一个时间点,只能有一个程序在处理器上运行!
 *    当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,
 *    它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,
 *    在一个时间段的线程代码运行时,其它线程处于挂起状。这种方式我们称之为并发(Concurrent)。
 * 
 * 
 * run()和start()的区别
 * 
 * start():真正的启动线程!并不是线程真正的执行!在调用start(),底层默认会执行run()!
 * 
 * run():普通的方法,也称为线程体!cpu分配时间片给当前线程的时候, 线程才真正的执行!
 * 
 *     比喻:
 *      玩游戏==》 魂斗罗
 *       现在只有一台电脑!很多人想玩?
 *       
 *      01.报名               
 *      02.排队                                 
 *      03.上机    (肯定是一个人在玩游戏) 执行run();             
 *      04.特殊情况  (两个人发生争执)                                                             
 *      05.游戏结束                                                                                                    
 *       
 *  线程的生命周期
 *     01.新生状态
 *         MyThread thread=new MyThread();
 *     02.就绪状态
 *          thread.start();
 *     03.运行状态
 *         cpu分配时间片给thread的时候,开始运行run()
 *     04.阻塞状态 
 *         sleep();wait();join()  
 *     05.死亡状态
 *        001.正常    run()执行完毕    正常的!
 *        002.异常     run()执行过程中,出现异常的情况,非正常退出!   
 * 
 *
 */
public class MyThread extends Thread {

    //重写run()
    @Override
    public void run() {
        for (int i = 1; i <=50; i++) {
            System.out.println(Thread.currentThread().getName()+"==="+i);
        }
    }
    
    //多个线程并发执行
    public static void main(String[] args) {
        //创建线程对象1
        MyThread thread1=new MyThread();
        //创建线程对象2
        MyThread thread2=new MyThread();
        //启动线程1
        thread1.start();
        //启动线程2
        thread2.start();
    }
    
/**        public static void main(String[] args) {  //只有一个主线程 main
            //创建线程对象1
            MyThread thread1=new MyThread();
            //创建线程对象2
            MyThread thread2=new MyThread();
            //调用thread类中的run()不是启动线程
            thread1.run();
            //调用thread2类中的run()不是启动线程
            thread2.run();
         }*/
}

/**
 * 
 * @author 小豆腐
 * 实现了Runnable接口  重写run()
 */
public class MyThread implements Runnable {

    
    //重写run()
    @Override
    public void run() {
        for (int i = 1; i <=50; i++) {
            System.out.println(Thread.currentThread().getName()+"==="+i);
        }
    }
    
    
    public static void main(String[] args) {
      //创建线程对象
        MyThread thread=new MyThread();
        //通过Thread带参构造创建线程的实例
        Thread runnable1 = new Thread(thread);
        Thread runnable2 = new Thread(thread);
        //开启线程
        runnable1.start();
        runnable2.start();
    }


}

 

 

 

 

 

/**
 * 
 * @author 小豆腐
 *     线程的状态
 */
public class MyThread implements Runnable {
    //重写run()
    @Override
    public void run() {
            try {
                System.out.println("线程运行状态........");
                System.out.println("线程阻塞状态........");
                //让当前线程休息一下  ******* run()不允许声明异常   只能捕获*****
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("线程异常死亡........");
            }
            System.out.println("线程正常死亡..........");
    }
    
    public static void main(String[] args) {
        //通过Thread带参构造创建线程的实例
        Thread t = new Thread(new MyThread());
        System.out.println("线程新生状态........");
        t.start();
        System.out.println("线程就绪状态........");
    }


}

 

 

/**
 * 
 * @author 小豆腐
 *     线程的优先级
 *  线程的优先级1--10  默认值 5
 *  优先级越高代表获得cpu资源的概率大,概率大并不代表一定能拿到资源!   
 */
public class MyThread implements Runnable {
    
    //重写run()
    @Override
    public void run() {
        for (int i = 1; i <=50; i++) {
            System.out.println(Thread.currentThread().getName()+"==="+i);
        }
    }
    
    
    public static void main(String[] args) {
        //通过Thread带参构造创建线程的实例
        Thread t1 = new Thread(new MyThread(),"线程A");
        Thread t2 = new Thread(new MyThread(),"线程B");
        System.out.println("t1默认的优先级:"+t1.getPriority());
        System.out.println("t2默认的优先级:"+t2.getPriority());
        //设置线程的优先级  MAX_PRIORITY=10   MIN_PRIORITY=1
        t1.setPriority(Thread.MAX_PRIORITY);
        t2.setPriority(Thread.MIN_PRIORITY);
        System.out.println("设置之后的优先级===============");
        System.out.println("t1默认的优先级:"+t1.getPriority());
        System.out.println("t2默认的优先级:"+t2.getPriority());
        //开启线程
        t1.start();
        t2.start();
        
        
    }


}

 

 join的使用

/**
 * 
 * @author 小豆腐
 *     线程调度:
 *     按照特定的机制为多个线程分配CPU资源的使用权!
 *     
 *  01.setPriority()设置线程的优先级
 *  02.sleep()在指定的毫秒数内让当前正在执行的线程休眠
 *  03.join() 等待该线程执行完毕
 *  04.yield()礼让,暂停当前正在执行的线程,执行其他的线程
 *  05.interrup()中断线程
 *  06.isAlive()判断线程是否处于活动状态
 */
public class MyThread implements Runnable {
    
    //重写run()
    @Override
    public void run() {
        for (int i = 1; i <=10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"===="+i);
        }
    }
}

 

测试代码

public class JoinTest {
    
    public static void main(String[] args) {
      System.out.println("=====join=====");
      Thread thread=new Thread(new MyThread(),"Join线程");
      thread.start(); //启动线程
      for (int i = 1; i <=20; i++) {
        if (i==5) {
             try {
                 //阻塞主线程!Join线程强制执行
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName()+"===="+i);
      }
    }
}

 

yield线程的礼让

/**
 * 
 * @author 小豆腐
 * 线程的礼让,也是一个概率问题
 */
public class MyThread implements Runnable {
    //重写run()
    @Override
    public void run() {
        for (int i = 1; i <=50; i++) {
            System.out.println(Thread.currentThread().getName()+"===="+i);
            if (i%3==0) {
                System.out.println("线程礼让.....");
                Thread.yield();
            }
        }
    }
}

测试类

public class YieldTest {
    
    public static void main(String[] args) {
      System.out.println("=====yield=====");
        Thread t1=new Thread(new MyThread(),"线程A");
        Thread t2=new Thread(new MyThread(),"线程B");
        //启动线程
        t1.start();
        t2.start();
    }
}

 

 

/**
 * 
 * @author 小豆腐
 * 01.线程不安全的网络购票
 * 
 */
public class MyThread implements Runnable {
     private  int  count=10;  //剩余的票数
     private  int  num=0;  //记录买到的第几张票
     
    //重写run()
    @Override
    public void run() {
        while(true){
            //没有票,跳出循环
            if (count<=0) {
                break;
            }
            //01.修改数据
            num++;
            count--;
            try {
                Thread.sleep(1000);  //让cpu重新分配时间片
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //02.显示信息
            System.out.println(Thread.currentThread().
                    getName()+"抢到了第"+num+"张票====剩余的票数:"+count);
        }
        
    }
}

 

/**
 * 
 * @author 小豆腐
 * 同步方法实现 ===》线程安全的网络购票
 * 
 */
public class MyThread implements Runnable {
     private  int  count=10;  //剩余的票数
     private  int  num=0;  //记录买到的第几张票
     private boolean flag=false;
     
     //给当前的方法加锁
     public  synchronized void  sale(){
         if (count<=0) { //票数少于0
            flag=true;
            return;
        }
                //01.修改数据
                num++;
                count--;
                try {
                    Thread.sleep(1000);  //让cpu重新分配时间片
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //02.显示信息
                System.out.println(Thread.currentThread().
                        getName()+"抢到了第"+num+"张票====剩余的票数:"+count);
     }
     
    //重写run()
    @Override
    public void run() {
        while(!flag){
            sale();
        }
    }
}

 

/**
 * 
 * @author 小豆腐
 * 同步代码块实现    ====》线程安全的网络购票
 * 
 * 
 *   多个并发线程访问同一个资源的同步代码块时:
 *   01.同一时刻只能有一个线程进入synchronized(this)代码块
 *   02.当一个线程访问synchronized(this)同步代码块时;其他的synchronized(this)
 *   同步代码块也被锁定
 *   03.当一个线程访问synchronized(this)同步代码块时;其他的线程可以访问该资源的
 *    非synchronized(this)代码块
 * 
 */
public class MyThread implements Runnable {
     private  int  count=10;  //剩余的票数
     private  int  num=0;  //记录买到的第几张票
     
    //重写run()
    @Override
    public void run() {
        while(true){
            /**  
             * 同步代码块
             * this:需要同步的对象,一般写成this
             */
            synchronized (this) {
                //没有余票,退出循环
                if (count<=0) {
                    break;
                }
                num++;
                count--;
                try {
                    Thread.sleep(1000);  //让cpu重新分配时间片
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //02.显示信息
                System.out.println(Thread.currentThread().
                        getName()+"抢到了第"+num+"张票====剩余的票数:"+count);
            }
        }
    }
}

 

 

 

public class SynchronizedTest {
    
    /**
     * 模拟三个人同时抢票
     * 
     * 多个线程在操作同一个共享的资源是,将引发数据不安全的问题!
     * 怎么解决这种不安全的问题???
     * 使用synchronized修饰的方法或者代码块!
     * synchronized:就是为当前的线程声明一个锁!
     */
    public static void main(String[] args) {
        MyThread thread=new MyThread();
        Thread t1=new Thread(thread, "老黄牛");
        Thread t2=new Thread(thread, "小白");
        Thread t3=new Thread(thread, "小黑");
        System.out.println("**************开始抢票******************");
        t1.start();
        t2.start();
        t3.start();
    }
}

 

/**
 * 
 *模拟10个特需号病人看病
 */
public class MyThread implements Runnable {
    
    @Override
    public void  run(){
        for (int i = 1; i <=10; i++) {
            System.out.println("******特需号:"+i+"号在看病");
            try {
                //看病时间是普通号的2倍
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

public class Test {
    
    public static void main(String[] args) {
        Thread t=new Thread(new MyThread());
        //特需号的优先级比普通号高
        t.setPriority(Thread.MAX_PRIORITY);
        t.start();
        //主线程模拟普通号看病
        for (int i = 1; i <=20; i++) {
            System.out.println("普通号:"+i+"号在看病");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //普通号看到第10人时,特需号病人必须全部看完
            if (i==10) {
                try {
                    t.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
        }
    }
}

 

 

/**
 * 模拟多人400接力跑
 *  
 *  使用同步方法
 *  多个线程访问同一个共享的资源!
 *  
 */
public class MyThread implements Runnable {
    private  int  meters=400;  //定义一共跑的米数
    
    
    //同步方法
    public  synchronized void running(){
        System.out.println(Thread.currentThread().getName()+"拿到了接力棒!***********");
        for (int i = 0; i < 100; i+=10) {
            System.out.println(Thread.currentThread().getName()+"跑了"+(i+10)+"米");
            try {
                Thread.sleep(100); //sleep没有释放锁
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //更新路程
        meters-=100;
    }
    
    @Override
    public void  run(){
        while(true){
             if (meters<100) {
                break;
            }
             running();  //开始跑步
        }
    }
}

 

 

/**
 * 模拟多人400接力跑
 *  
 *  使用同步代码块
 *  多个线程访问同一个共享的资源!
 *  
 */
public class MyThread implements Runnable {
    private  int  meters=400;  //定义一共跑的米数
    
    @Override
    public void  run(){
        while(true){
            synchronized (this) { //同步代码块
                 if (meters<100) {
                        break;
                    }
                     System.out.println(Thread.currentThread().getName()+"拿到了接力棒!***********");
                        for (int i = 0; i < 100; i+=10) {
                            System.out.println(Thread.currentThread().getName()+"跑了"+(i+10)+"米");
                            try {
                                Thread.sleep(100); //sleep没有释放锁
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        //更新路程
                        meters-=100;
            }
        }
    }
}

 

public class Test {
    
    public static void main(String[] args) {
        //创建线程对象
        MyThread thread=new MyThread();
        Thread t1=new Thread(thread, "1号选手");
        Thread t2=new Thread(thread, "2号选手");
        Thread t3=new Thread(thread, "3号选手");
        Thread t4=new Thread(thread, "4号选手");
        //开始跑步
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        
    }
}

 

 

public class MyThread implements Runnable {
   private int  index=0;   //集合中的下标
   private  ArrayList<String> list=new ArrayList<String>();
    
    @Override
    public void  run(){
        while(true){
            if (index>100) {
                break;
            }
            list.add(index+"");
            System.out.println("下标:"+index+"的值是:=="+list.get(index));
            index++;  
            }
        }
    }
public class Test {
    
    public static void main(String[] args) {
        //创建线程对象
        MyThread thread=new MyThread();
        //10个线程往集合中增加数据
        for (int i = 0; i <10; i++) {
            new Thread(thread).start();
        }
        
    }
}

 

 

 

 

 

 

 

 

public class SaleTicket implements Runnable{
     //库存票数
     private  int   tickets=100;
    
    /*
     * 卖票  同步代码方法 比 同步代码块 性能高!  但是功能是一致的!
     * 一个类中可以有多个 同步方法 或者同步代码块
     * 
     * 当 一个对象调用这个对象中的同步方法时!  还可以同时调用其他的同步方法!  无需等待!
     * 但是  一个对象执行这个对象中的同步代码块! 这个对象中的所有同步代码块 都上锁了! 都必须等待!
     * 
     * 同步代码块 锁的是 对象  并不是 代码块!
     * 
     */
     private synchronized  void  sale(){
         if (tickets>0) {
            System.out.println(Thread.currentThread().getName()+"卖出了"+tickets+"票");
            //票数-1
            tickets--;
        }
         try {
            Thread.sleep(2);  //让cpu重新分配时间片
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
     }

    @Override
    public void run() {
         while (tickets>0) {
            sale();
        }
    }

    public static void main(String[] args) {
        SaleTicket ticket=new SaleTicket();
        Thread t1=new Thread(ticket);
        Thread t2=new Thread(ticket);
        Thread t3=new Thread(ticket);
        Thread t4=new Thread(ticket);
        //设置窗口名称
        t1.setName("1号窗口");
        t2.setName("2号窗口");
        t3.setName("3号窗口");
        t4.setName("4号窗口");
        //开始卖票
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        
    }
    
    
    
    
    
    
}
同步代码方法实现卖票

 

public class SaleTicket2 implements Runnable{
     //库存票数
     private  int   tickets=100;
    
    @Override
    public void run() {
         while (tickets>0) {
            //同步代码块
             synchronized (this) {
                 if (tickets>0) {
                        System.out.println(Thread.currentThread().getName()+"卖出了"+tickets+"票");
                        //票数-1
                        tickets--;
                    }
                 try {
                        Thread.sleep(2);  //让cpu重新分配时间片
                    } catch (InterruptedException e) {  //线程 阻塞异常!
                        e.printStackTrace();
                    }
            }
        }
    }
    
    
    
    
    
    public static void main(String[] args) {
        SaleTicket2 ticket=new SaleTicket2();
        Thread t1=new Thread(ticket);
        Thread t2=new Thread(ticket);
        Thread t3=new Thread(ticket);
        Thread t4=new Thread(ticket);
        //设置窗口名称
        t1.setName("1号窗口");
        t2.setName("2号窗口");
        t3.setName("3号窗口");
        t4.setName("4号窗口");
        //开始卖票
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    
    }
    
}
同步代码块实现卖票

 

/*
Runnable  Thread  Callable     Future  多线程


Runnable  与 Callable 区别
01.Runnable默认规定执行的方法时run();Callable默认规定执行的方法时call();
02.Runnable的run()没有返回值,Callable中的call()具有返回值
03.run()不能声明异常!必须内部处理!  call()可以声明异常
04.运行Callable的时候可以 拿到一个Future对象 !



Future是一个模式!
  核心思想====》  原本需要等待的时间段,现在可以去做一些其他的业务逻辑!
假设  现在有一个 具有返回值的A()   还有一个B() 和C()

之前我们调用A() 必须等待A()返回结构之后  才能调用 B()或者C()

现在我们调用A() 不须等待A()返回结构之后  也能调用 B()或者C() Future

*/
小结

 

验证 锁的不是代码块,而是对象!

class MyThread  implements  Runnable{  
      
    /**
     * 同步代码方法
     * 01.在不同的对象访问的时候,都可以进入这个方法
     * 如果说锁住的是代码块,那么其他的对象就不会访问这个方法
     * 02.在相同对象访问的时候,会开始 结束  输出完毕之后 继续下次的访问
     */
    public  synchronized void test() {  
        System.out.println("test()开始......");  
        try {  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("test()结束......"); 
        }
    
    //线程要执行的run()
    public void run() {  
        test();  //调用上面的代码
    }  
    
    
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {  
            /**
             * 每次都会创建一个新的对象
             * 那么每个对象都会进入test()
             */
            Thread thread = new Thread(new MyThread());  
            thread.start();  
        } 
    }
   /** 相同的对象
    *  public static void main(String[] args) {
        MyThread myThread=new MyThread();
         for (int i = 0; i < 3; i++) {  
              // 只有一个新的对象那么对象会按照顺序进入test()
                Thread thread = new Thread(myThread);  
                thread.start();  
          } 
    }
    */
    
}  
  
同步代码方法
class MyThread01  implements  Runnable{  
      
    /**
     * 同步代码块   效果和同步代码方法一样
     * 01.在不同的对象访问的时候,都可以进入这个方法
     * 如果说锁住的是代码块,那么其他的对象就不会访问这个方法
     * 02.在相同对象访问的时候,会开始 结束  输出完毕之后 继续下次的访问
     */
    public   void test() { 
        //这是使用的是this  其实锁的还是当前的对象
        synchronized(this){
        System.out.println("test()开始......");  
        try {  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("test()结束......"); 
        }
    }
    //线程要执行的run()
    public void run() {  
        test();  //调用上面的代码
    }  
    
    
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {  
            /**
             * 每次都会创建一个新的对象
             * 那么每个对象都会进入test()
             */
            Thread thread = new Thread(new MyThread01());  
            thread.start();  
        } 
    }
    
   /**相同的对象 
    * public static void main(String[] args) {
        MyThread myThread=new MyThread();
         for (int i = 0; i < 3; i++) {  
              // 只有一个新的对象那么对象会按照顺序进入test()
                Thread thread = new Thread(myThread);  
                thread.start();  
          } 
    }
    */
    
}  
同步代码块

 

class MyThread02  implements  Runnable{  
      
    public   void test() { 
        /**
         * 这是使用的是MyThread02.class  这是锁住类对应的class对象
         * 其他的对象也是不能访问的!
         */
        synchronized(MyThread02.class){
        System.out.println("test()开始......");  
        try {  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("test()结束......"); 
        }
    }
    //线程要执行的run()
    public void run() {  
        test();  //调用上面的代码
    }  
    
    
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {  
            Thread thread = new Thread(new MyThread02());  
            thread.start();  
        } 
    }
    
   /**相同的对象 
    * public static void main(String[] args) {
        MyThread myThread=new MyThread();
         for (int i = 0; i < 3; i++) {  
              // 只有一个新的对象那么对象会按照顺序进入test()
                Thread thread = new Thread(myThread);  
                thread.start();  
          } 
    }
    */
    
}  
锁住class对象

 

posted @ 2016-11-17 14:22  @小葱拌豆腐  阅读(886)  评论(0编辑  收藏  举报

霸气