zoukankan      html  css  js  c++  java
  • Java自学课程笔记8

    2021年3月2日20点21分
    JAVA自学课程笔记8:
    
        synchronized(同步)修饰代码块:
            格式:
                synchronized(object aa){
                    //同步代码块
                }
    
            含义:判断aa是否已经被其他线程霸占(术语:锁定),如果发现已经被其他线程霸占。则当前线程陷入等待中,如果发现aa没有被其他线程霸占,则当前线程霸占在aa对象,并执行语句内的同步代码块在当前线程执行同步代码块代码时,其他线程将无法再执行同步代码块的代码(因为当前线程已经霸占了aa对象),当前线程执行完同步代码块的代码后,会自动释放对aa对象的霸占,此时其他线程会相互竞争对aa的霸占,最终CPU会选择其中的某个线程执行。霸占住的那个对象术语叫:监听器。
    
            最终导致的结果是:一个线程正在操作某资源的时候,将不允许其它线程操作该资源,即一次只允许一个线程处理该资源。
    
            火车买票程序:
                Test1:
                    class A implements Runnable{
                        public static int tickets = 100;
    
                        public void run(){
                            while(true){
                                if(tickets > 0){
                                    System.out.printf("%s线程正在卖出第%d张票", Thread.currentThread().getName(), tickets);
                                    tickets --;
                                }else{
                                    break;
                                }
                            }
                        }
                    }
    
                    public class Test1{
                        public static void main(String[] args){
                            A aa1 =  new A();
                            Thread t1 = new Thread(aa1);
                            t1.start();
    
                            A aa2 = new A();
                            Thread t2 = new Thread(aa2);
                            t2.start();
                        }
                    }
                //虽然用的是static修饰的tickets,但是还是会在执行语句时发生落差,一个对象在不同线程被同时执行且产生时间差,例如1号线程在卖第99张票时,2号线程已经在卖第94张票了,假如正好下一次轮到了1号线程卖,就卖到了第93张。同一个对象被两个线程同时占用,应发程序bug。
                    
                Test2:
                    class A implements Runnable{
                        public static int tickets = 100;
                        String str = new String("我是一个字符对象!");
    
                        public void run(){
                            while(true){
                                synchronized(str){
                                    if(tickets > 0){
                                        System.out.printf("%s线程正在卖出第%d张票
    ", Thread.currentThread().getName(), tickets);
    
                                        tickets --;
                                    }else{
                                        break;
                                    }
                                }
                            }
                        }
                    }
    
                    public class Test2{
                        public static void main(String[] args){
                            A aa = new A();
                            Thread t1 = new Thread(aa);
                            t1.start();
    
                            Thread t2 = new Thread(aa);
                            t2.start();
                        }
                    }
    
    
                synchronized修饰一个方法时,实际霸占的是该方法的this指针所指的对象(即synchronized修饰一个方法时,实际霸占的是正在调用该方法的对象)当一个线程进入这个方法后,这个方法的大门就会暂时关闭(不许其他线程进入)直到这个线程走出这个方法后,该方法的大门才会敞开。当然,这个关闭只是对于该类的当前实例有效,多个实例的对象仍然可以同时执行。若Test2的run()方法用synchronized修饰,运行结果会是永远只有一个线程在卖票。
        
    
        生产和消费程序:
            class SynStack{
                private int cnt =  0;
                private char[] data = new char[6];
    
                public synchronized void push(char c){
                    while(cnt==data.length){
                        try{
                            this.wait();
                        }catch(InterruptedException e){}
                    }
                    this.notify();
    
                    data[cnt] = c;
                    cnt++;
                    System.out.println("produced    #: "+c);
                }
    
                public synchronized char pop(){
                    char c;
    
                    while(cnt==0){
                        try{
                            this.wait();
                        }catch(InterruptedException e){}
                    }
                    this.notify();
                    cnt--;
                    System.out.println("consumed    *: "+data[cnt]);
                    return data[cnt];
                }
            }
    
    
            class Producer implements Runnable{
                private SynStack ss = null;
    
                public Producer(SynStack ss){
                    this.ss = ss;
                }
                
                public void run(){
                    char c;
    
                    for(int i=0; i<20; ++i){
                        c = (char)('1'+i);
                        ss.push(c);
                    }
                }
            }
    
    
            class Consumer implements Runnable{
                private SynStack ss = null;
    
                public Consumer(SynStack ss){
                    this.ss = ss;
                }
    
                public void run(){
                    for(int i=0; i<20; ++i){
                        try{
                            Thread.sleep(2000);
                        }catch(InterruptedException e){}
    
                        ss.pop();
                    }
                }
            }
    
    
            public class test1{
                public static void main(String[] args){
                    SynStack ss = new SynStack();
                    Producer p = new Producer(ss);
                    Consumer c = new Consumer(ss);
                    Thread t1 = new Thread(p);
                    t1.start();
    
                    Thread t2 = new Thread(c);
                    t2.start();
                }
            }
        //满足一个线程消费,另外一个线程生产且具有同步性。
  • 相关阅读:
    linux杀死僵尸进程
    通过dd命令显示硬盘的读写性能
    linux 压缩与解压缩
    linux云主机cpu一直很高降不下来,系统日志报nf_conntrack: table full, dropping packet.
    vsftp配置文件详解
    linux中ping带时间及打印内容到文件
    atop工具检测linux硬件异常
    windows连接服务端的域名正常,linux却不通,(针对于负载均衡后端节点设置)
    有你的地方就是天堂
    Java 异常 —— java.io.InvalidClassException: javax.xml.namespace.QName; local class incompatible
  • 原文地址:https://www.cnblogs.com/yinjx/p/14647938.html
Copyright © 2011-2022 走看看