• Java基础9-死锁;String;编码


    昨日内容回顾

    1. 死锁案例

       class DeadLock{
           public static void main(String[] args){
               Pool pool = new Pool();
               Producer p1 = new Producer("p1",pool);
               Consumer c1 = new Consumer("c1",pool);
               Consumer c2 = new Consumer("c2",pool);
               p1.setName("p1");
               c1.setName("c1");
               c2.setName("c2");
      
               p1.start();
               c1.start();
               c2.start();
           }
       }
      
       class Producer extends Thread{
           String name;
           Pool pool;
           public Producer(String name, Pool pool){
               this.name = name;
               this.pool = pool;
           }
      
           public void run(){
               while(true){
                   pool.add();
               }
           }
       }
      
       class Consumer extends Thread{
           String name;
           Pool pool;
           public Consumer(String name, Pool pool){
               this.name = name;
               this.pool = pool;
           }
           public void run(){
               while(true){
                   pool.remove();
               }
           }
       }
      
       class Pool{
           private int MAX=1;
           private int count;
           public synchronized void add(){
               String name = Thread.currentThread().getName();
               while(count>=MAX){
                   try{
                       System.out.println(name+":"+"wait()");
                       this.wait();
                   }
                   catch(Exception e){}
               }
               System.out.println(name+":"+(++count));
               System.out.println(name+":"+"notify()");
               this.notify();
           }
      
           public synchronized void remove(){
               String name = Thread.currentThread().getName();
               while(count<MAX){
                   try{
                       System.out.println(name+":"+"wait()");
                       this.wait();
                   }
                   catch(Exception e){}
               }
               System.out.println(name+":"+(--count));
               System.out.println(name+":"+"notify()");
               this.notify();
           }
       }
      
    2. 同步方法中,wait()与notify()执行流程

       class WaitDemo{
           public static void main(String[] args){
               Cave cave = new Cave();
               Car c1 = new Car("奔驰",cave);
               Car c2 = new Car("宝马",cave);
               c1.start();
               c2.start();
      
               try{
                   Thread.sleep(5000);
                   synchronized(cave){
                       cave.notifyAll();
                   }
               }
               catch(Exception e){}
           }
       }
      
       class Cave{
       }
       class Car extends Thread{
           private String name;
           private Cave cave;
           public Car(String name, Cave cave){
               this.name = name;
               this.cave = cave;
           }
      
           public void run(){
               synchronized(cave){
                   System.out.println(name+"进洞了!");
                   try{
                       cave.wait();
                   }
                   catch(Exception e){}
                       System.out.println(name+"wait后代码");
               }
           }
       }
      
    3. 设置线程优先级

       class WaitDemo{
           public static void main(String[] args){
               Cave cave = new Cave();
               Car c1 = new Car("奔驰",cave);
               Car c2 = new Car("宝马",cave);
           
               //设置线程优先级
               Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
               c1.setPriority(Thread.MIN_PRIORITY);
               c2.setPriority(Thread.NORM_PRIORITY);
               System.out.println("c1.priority:"+c1.getPriority());
               System.out.println("c2.priority:"+c2.getPriority());
               System.out.println("main.prio : " +Thread.currentThread().getPriority());
           
               c1.start();
               c2.start();
      
               try{
                   Thread.sleep(5000);
                   synchronized(cave){
                       cave.notifyAll();
                   }
               }
               catch(Exception e){}
           }
       }
      
       class Cave{
       }
       
       class Car extends Thread{
           private String name;
           private Cave cave;
           public Car(String name, Cave cave){
               this.name = name;
               this.cave = cave;
           }
           
           public void run(){
               synchronized(cave){
                   System.out.println(name+"进洞了!");
                   try{
                       cave.wait();
                   }
                   catch(Exception e){}
                   System.out.println(name+"wait后代码");
               }
           }
       }
      

    作业讲解

    1. 一共100个馒头,40个工人,每个工人最多能吃3个馒头,使用多线程输出所有工人吃馒头的情况

       class ThreadDemo{
           public static void main(String[] args){
               Basket basket = new Basket();
               Worker w[] = new Worker[40];
               for(int i=0;i<40;i++){
                   w[i] = new Worker("worker-"+i,basket);
               }
               for(int i=0;i<40;i++){
                   w[i].start();
               }
           }
       }
      
       //放馒头的篮子
       class Basket{
           private int No = 100;
      
           //取馒头
           public int getNo(){
               if(No<=0){
                   return -1;
               }
               else{
                   return No--;
               }
           }
       }
      
       //工人线程类
       class Worker extends Thread{
           private static Basket basket;
           private String name;
           private int sumNo=0;//总共吃的馒头数
      
           public Worker(String name,Basket basket){
               this.basket = basket;
               this.name = name;
           }
      
           public void run(){
               while(true){
                   synchronized(basket){
                       if(sumNo>=3){
                           return;
                       }
                       int no = basket.getNo();
                       if(no==-1){
                           return;
                       }
                       else{
                           sumNo++;
                           System.out.println(name+"吃了第"+no+"个馒头,共吃了"+sumNo+"个馒头");
                       }    
                   }
                   Thread.yield();
               }    
           }
       }
      
    2. 5辆汽车过隧道,隧道一次只能通过一辆汽车。每辆汽车通过时间不固定,
      机动车通过时间3秒,三轮车通过时间5秒,畜力车通过时间10秒,5辆车分别是2辆机动车,2辆畜力车,1辆三轮车,通过多线程模拟通过隧道的情况。提示:Car ThreeCar CowCar

       class ThreadDemo{
           public static void main(String[] args){
               Cave cave = new Cave();
               new Car(cave,"汽车1",3).start();
               new Car(cave,"汽车2",3).start();
               new ThreeCar(cave,"三轮车",5).start();
               new CowCar(cave,"畜力车1",10).start();
               new CowCar(cave,"畜力车2",10).start();
           }
       }
      
       //隧道,山洞
       class Cave{
       }
      
       //机动车线程类
       class Car extends Thread{
           private Cave cave;
           private int sec;
           private String name;
      
           public Car(Cave cave, String name, int sec){
               this.cave = cave;
               this.name = name;
               this.sec = sec;
           }
      
           public void run(){
               synchronized(cave){
                   System.out.println(name+"进洞了!"+new java.util.Date());
                   try{
                       Thread.sleep(sec*1000);
                   }
                   catch(Exception e){}
                   System.out.println(name+"出洞了!"+new java.util.Date());
               }
           }
       }
      
       //三轮车线程类
       class ThreeCar extends Thread{
           private Cave cave;
           private int sec;
           private String name;
      
           public ThreeCar(Cave cave, String name, int sec){
               this.cave = cave;
               this.name = name;
               this.sec = sec;
           }
           public void run(){
               synchronized(cave){
                   System.out.println(name+"进洞了!"+new java.util.Date());
                   try{
                       Thread.sleep(sec*1000);
                   }
                   catch(Exception e){}
                   System.out.println(name+"出洞了!"+new java.util.Date());
               }
           }    
       }
      
       //畜力车线程类
       class CowCar extends Thread{
           private Cave cave;
           private int sec;
           private String name;
      
           public CowCar(Cave cave, String name, int sec){
               this.cave = cave;
               this.name = name;
               this.sec = sec;
           }    
      
           public void run(){
               synchronized(cave){
                   System.out.println(name+"进洞了!"+new java.util.Date());
                   try{
                       Thread.sleep(sec*1000);
                   }
                   catch(Exception e){}
                   System.out.println(name+"出洞了!"+new java.util.Date());
               }
           }
       }    
      
    3. 用多线程模拟蜜蜂和熊的关系
      蜜蜂是生产者,熊是消费者,蜜蜂生产蜂蜜是累加的过程,熊吃蜂蜜是批量(满20吃掉)的过程,生产者和消费者之间使用通知方式告知对方,注意不能出现死锁现象。
      100只蜜蜂,每次生产的蜂蜜是1
      熊吃蜂蜜是20(批量的情况)

       class ThreadDemo{
           public static void main(String[] args){
               Pot pot = new Pot();
               for(int i=1;i<=100;i++){
                   new Bee("蜜蜂-"+i,pot).start();
               }
               new Bear("熊大",pot).start();
               new Bear("熊二",pot).start();
           }
       }
       //蜜罐
       class Pot{
           private int MAX = 20;//最大值
           private int count;//当前量
      
           //添加蜂蜜,+1
           public synchronized int add(){
               while(count >= MAX){//若是if则下次进入线程,就不再去判断,存在问题
                   try{
                       this.notifyAll();
                       this.wait();
                   }
                   catch(Exception e){
                       e.printStackTrace();
                   }
               }
               return ++count;
           }
      
           //移除蜂蜜,-MAX
           public synchronized void remove(){
               while(count< MAX ){
                   try{
                       this.wait();
                   }
                   catch(Exception e){
                       e.printStackTrace();
                   }
               }
               count=0;
               this.notifyAll();
           }
       }
       //蜜蜂,生产者线程类
       class Bee extends Thread{
           private Pot pot;
           private String name;
           public Bee(String name, Pot pot){
               this.name = name;
               this.pot = pot;
           }
           public void run(){
               while(true){
                   int n = pot.add();
                   System.out.println(name+"生产了:"+n);
               }
           }
       }
       //熊,消费者线程类
       class Bear extends Thread{
           private Pot pot;
           private String name;
           public Bear(String name, Pot pot){
               this.name = name;
               this.pot = pot;
           }
           public void run(){
               while(true){
                   pot.remove();
                   System.out.println(name+"吃掉了蜂蜜:20!");
               }
           }
       }
      

    创建线程的方式

    1. 继承Thread类

    2. 实现Runnable接口{public void run();}

       class Man extends Person implements Runnable{
           public void run(){
           ...
           }
       }
      
       new Car().start();
       new Thread(new Man()).start();
      

    java.lang.Runnable

    1. 接口

    2. public void run();

    3. 供现有类实现线程功能

    4. 使用Runnable对象创建线程

    5. 静态同步方式是使用class作为锁

    6. 非静态同步方式是使用当前对象作为锁

       new Thread(Runnable r).start();
       class Car implements Runnable{
       ...
       //静态同步方法
       static synchronized void xxx(){
      
       }
       }
       new Thread(Runnable r).start()
      

    IDE

    集成开发环境, integrate development environment
    eclipse 快捷键:

    • alt + / //代码辅助
    • alt + 上箭头 //向上移动一行
    • alt + 下箭头 //向上移动一行
    • alt + shift + 上箭头 //向上复制一行
    • alt + shift + 下箭头 //向下复制一行
    • ctrl + D //删除一行
    • ctrl + shift + / //多行注释

    String

    1. 常量

       String str = "xxx";
       str = "ddd";
       for(i<10000){
         name = name + "" + i;
       }//堆溢出
       byte b = (int)1234;
       //int a = (int)"123";
       //String name = (String)123;
       String name = 123 + "";
      
       Object o = new Dog();
       Dog d = (Dog)o;
      
    2. 创建String 的区别

       //一个对象
       String str1 = "abc";//在字符串池中开辟了空间
       //两个对象
       String str2 = new String("abc");//在堆区分配了内存空间
      
    3. split(String s) // 按照指定的字符切割字符串,形成String数组

       "hello,,,world,".split(",");//最后的,不会生效
      
    4. == //判断是否是同一对象。判断对象的内存地址

    5. equals //是判断两个对象内容是否相同。

    6. substring(int start) //取子串,包含start

    7. substring(int start,int end) //取子串,前包后不包

    8. 重写subString(String src,int beginIndex,int length) //按索引及长度取子串,要有健壮性

       public static String subString(String src, int beginIndex, int length) throws Exception {
           if(src==null) {
               throw new Exception("源串为空");
           }
           if(!(beginIndex>=0 && beginIndex<src.length())) {
               throw new Exception("起始索引无效");
           }
           if(!(length>0 && (beginIndex+length)<=src.length())) {
               throw new Exception("长度无效");
           }
           return src.substring(beginIndex,beginIndex+length);
       }
      

    包装类

    1. byte Byte

    2. short Short

    3. int Integer

    4. long Long

    5. float Float

    6. double Double

    7. char Character

    8. boolean Boolean

    自动装箱:Integer i = 12; // Integer i = new Integer(12);
    自动拆箱:Integer i =12; i++

    包装类与基本数据类型区别

    1. 包装类是对象,默认值是null;

    2. 数字型基本数据类型默认是0;

    3. 基本数据类型可以直接参与运算;

    编码初始

    电报,电脑的传输,存储都是01010101

    0000110 晚
    1010100 上
    0010100 喝
    0010111 点
    0000001 儿

    000010 1010100 0010100 0010111 0000001

    最早的'密码本'

    1. ascii
      7位二进制,涵盖了英文字母大小写,特殊字符,数字。
      01000001 A
      01000010 B
      01000011 C
      ascii,一个字节最多8位, 只能表示256种可能,太少

    2. 存储单位换算
      1bit 8bit = 1byte
      1byte 1024byte = 1KB
      1KB 1024kb = 1MB
      1MB 1024MB = 1GB
      1GB 1024GB = 1TB

    3. 万国码 unicode

      • 起初:
        1个字节可以表示所有的英文,特殊字符,数字等等
        2个字节,16位表示一个中文,不够,unicode一个中文用4个字节,32位
        你 00000000 00000000 00000000 00001000

      • Unicode 升级 utf-8 utf-16 utf-32
        utf-8 一个字符最少用8位去表示:
        1). 英文用8位 一个字节
        2). 欧洲文字用16位去表示 两个字节
        3). 中文用24位去表示 三个字节
        utf-16 一个字符最少用16位去表示

    4. gbk
      中国人自己发明的,一个中文用两个字节,16位表示。

       String str = "a中b国c";
       byte[] bytes = str.getBytes("iso8859-1");
       System.out.println(bytes.length); //5, 欧洲码,没有中文字典
       System.out.println(new String(bytes,"iso8859-1")); //a?b?c
       
       bytes = str.getBytes("gbk");
       System.out.println(bytes.length); //7,一个字节表示英文字母,两个字节表示一个中文
       System.out.println(new String(bytes,"gbk")); //a中b国c
       
       bytes = str.getBytes("utf-8");
       System.out.println(bytes.length);//9, 英文一个字节,中文三个字节
       System.out.println(new String(bytes,"utf-8"));
      
       bytes = str.getBytes("unicode");// -2 -1 0 97 78 45 0 98 86 -3 0 99
       System.out.println(bytes.length);//12,中文四个字节,英文一个字节?为何是12?
       System.out.println(new String(bytes,"unicode"));
       
       String str2 = "a";
       byte[] bytes2 = str2.getBytes("unicode");//-2 -1 0 97
      
       String str3 = "中";
       byte[] bytes3= str3.getBytes("unicode");//-2 -1 78 45
       
       String str4 = "b";
       byte[] bytes4 = str4.getBytes("unicode");//-2 -1 0 98
        
       String str5 = "国";
       byte[] bytes5 = str5.getBytes("unicode");//-2 -1 86 -3
       
       String str6 = "c";
       byte[] bytes6 = str6.getBytes("unicode");//-2 -1 0 99
      

    作业

    1. substring(String str, int beginIndex, int length);
      返回一定长度的子串

    2. 找到自己名字对应的Unicode码

  • 相关阅读:
    考试备忘
    php代码规范
    text-indent: -999px;是什么意思
    MYSQL中的普通索引,主健,唯一,全文索引区别
    Mysql索引介绍及常见索引(主键索引、唯一索引、普通索引、全文索引、组合索引)的区别
    flush privileges是什么意思?
    大长今
    深入理解this对象
    如何将js与HTML完全脱离
    php页面相互调用的知识点
  • 原文地址:https://www.cnblogs.com/SweetZxl/p/10079467.html
Copyright © 2020-2023  润新知