• 线程2-线程同步


    1、线程安全问题原因?
    由于一个线程在操作一个共享数据时,未执行完毕的情况下,另外的线程参与进来,导致共享数据存在安全问题
    2、如何解决线程安全问题?
    一个线程操作完共享数据以后,其他线程才可以操作共享数据
    3、java使用线程同步机制实现,线程安全
    方式一:同步代码块
    synchronized(Object obj){ //可以是任何一个对象,对象不能为线程私有
    //操作共享数据的代码块
    }
    (1)共享数据
    (2)同步监视器(上面的obj参数),对象锁,由一个对象充当,哪个类获取到对象锁,就执行同步代码
    方式二:
    (1)将需要同步的代码块,放到一个方法,对方法加同步
    (2)同步方法,对象锁默认this

    4、同步要注意的:

    (1)synchronized修饰非静态方法,里面是当前类的对象
    (2)synchronized静态方法的锁是当前类的字节码文件对象 类名.class
    (3)多个线程必须用同一把对象锁,否则锁无效,非static锁定实列,static 锁定类

    5、例1,继承方式实现多窗口卖票,非线程安全

    package com.thread.test;
    
    
    
    /**
     * 
     * 继承方式:模拟火车站售票
     *存在线程安全问题
     */
    class Window extends Thread{
        static int ticket = 100;
        static int k = 0 ;
        @Override
        public void run(){
            while(true){
                if(ticket > 0){
                    System.out.println(Thread.currentThread().getName()+"售票号码:"+ticket);
                    k++;
                    ticket --;
                }else{
                    System.out.println("All "+k);
                    break;
                }
            }
        }
    }
    public class TestWindowExtends{
        
        public static void main(String[] args) {
            Window w1 = new Window();
            Window w2 = new Window();
            Window w3 = new Window();
            
            w1.setName("窗口1");
            w2.setName("窗口2");
            w3.setName("窗口3");
            
            w1.start();
            w2.start();
            w3.start();
        }
    }

    例2,继承方式多窗口卖票,线程安全

    package com.thread.test;
    
    
    
    /**
     * 
     * 继承方式:模拟火车站售票
     *存在线程安全问题
     */
    class Window3 extends Thread{
        static int ticket = 100;
        static int k = 0 ;
        static Object obj = new Object();
        @Override
        public void run(){
            
                while(true){
                    synchronized(obj){//注意和实现implements方法对象锁的不同
                    if(ticket > 0){
                        System.out.println(Thread.currentThread().getName()+"售票号码:"+ticket);
                        k++;
                        ticket --;
                    }else{
                        System.out.println("All "+k);
                        break;
                    }
                }
            }
        }
    }
    public class TestWindowExtends同步代码块{
        
        public static void main(String[] args) {
            Window w1 = new Window();
            Window w2 = new Window();
            Window w3 = new Window();
            
            w1.setName("窗口1");
            w2.setName("窗口2");
            w3.setName("窗口3");
            
            w1.start();
            w2.start();
            w3.start();
        }
    }

    例3、实现Runnable接口实现多窗口卖票,线程安全,同步代码块

    package com.thread.test;
    
    /**
     *    1、线程安全问题原因?
     *        由于一个线程在操作一个共享数据时,未执行完毕的情况下,另外的线程参与进来,导致共享数据存在安全问题 
     *    2、如何解决线程安全问题?
     *        一个线程操作完共享数据以后,其他线程才可以操作共享数据
     *    3、java使用线程同步机制实现,线程安全
     *        方式一:同步代码块
     *            synchronized(Object obj){ //可以是任何一个对象,对象不能为线程私有
     *                //操作共享数据的代码块
     *            }
     *            (1)共享数据
     *            (2)同步监视器(上面的obj参数),对象锁,由一个对象充当,哪个类获取到对象锁,就执行同步代码
     *        方式二:
     *            (1)将需要同步的代码块,放到一个方法,对方法加同步
     *            (2)同步方法,对象锁默认this
     */
    class Window2 implements Runnable{
        int ticket = 100;
        int count = 0;
        @Override
        public void run() {
            //this表示当前对象,因为,在下面的main方法中,只创建了一次Windows2对象,所以,this代表的当前对象是三个线程共享的,对象锁唯一。所以可以用this
            //而在继承方式中,对象锁不能用this,因为,在main方法中Windows对象被创建了3次,this对应三个对象,对象不唯一,所以不能用this
            //多个线程用同一把对象锁
            
                while(true){
                    synchronized(this){//不要写到while外面,while外面,就会只有线程1执行代码
                    if(ticket >0){
                        System.out.println("线程"+Thread.currentThread().getName()+"出售票号:"+ticket);
                        ticket --;
                        count ++;
                    }else{
                        System.out.println("Aall "+count);
                        break;
                    }
                }
                
            }
            
            
        }
        
    }
    
    public class TestWindowImplements同步代码块 {
        public static void main(String[] args) {
            //继承方式只需创建一个Window对象
            Window1 window = new Window1();
            
            //三个线程操作同一个对象
            Thread t1 = new Thread(window);
            t1.setName("t1");
            Thread t2 = new Thread(window);
            t2.setName("t2");
            Thread t3 = new Thread(window);
            t3.setName("t3");
            t1.start();
            t2.start();
            t3.start();
        }
    }

    例4、实现Runnable接口实现多窗口卖票,线程安全,同步方法

    package com.thread.test;
    
    class Window4 implements Runnable{
        int ticket = 100;
        int count = 0;
        @Override
        public void run() {
            while(true){
                sell();
            }
            
        }
        
        //对象锁默认this
        public synchronized void sell(){
            if(ticket >0){
                System.out.println("线程"+Thread.currentThread().getName()+"出售票号:"+ticket);
                ticket --;
                count ++;
            }
        }
        
    }
    
    public class TestWindowImplements同步方法 {
        public static void main(String[] args) {
            //继承方式只需创建一个Window对象
            Window4 window = new Window4();
            
            //三个线程操作同一个对象
            //由于三个线程会同时操作ticket这一变量,所以会出现同步问题,所以要加同步
            Thread t1 = new Thread(window);
            t1.setName("t1");
            Thread t2 = new Thread(window);
            t2.setName("t2");
            Thread t3 = new Thread(window);
            t3.setName("t3");
            t1.start();
            t2.start();
            t3.start();
        }
    }

    需要注意的事项都写在注释里

  • 相关阅读:
    十个html5代码片段,超实用,一定要收藏
    零基础学编程,我想给你这五条建议
    Java 程序员开发常用的工具(二)
    Java 程序员开发常用的工具(一)
    前端人才饱和?平均年薪25W难求优质程序员!
    java基础学习 了解这些很有必要
    初学HTML5技术开发笔记整理
    HTML5移动开发学习笔记之02-CH4-HTML5 Web表单
    web前端笔记之Web前端的安全与漏洞
    5.SSH 免密码登陆
  • 原文地址:https://www.cnblogs.com/fubaizhaizhuren/p/5066531.html
Copyright © 2020-2023  润新知