多线程案例与同步

同步方法实现卖票:

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对象
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();  
          } 
    }
    */
    
}  

原文地址:https://www.cnblogs.com/xiaobaizhang/p/7761647.html