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接口

     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码

posted @ 2018-12-06 20:59  Shinesu  阅读(157)  评论(0编辑  收藏  举报