栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

day22学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

day22学习笔记

一、回顾
1.方法多参数
  语法:
    访问修饰符  返回值类型 方法名称(数据类型 ... 变量名) {
         方法体
         return 返回值;
    }
  注意点: 多参数本质就是一个数组
2.Properties
   public Object setProperty(String key,String value) ==>设置键值对
   public String getProperty(String key) 根据键获取值
   public Set stringPropertyNames() 返回此属性列表中的键集
   public void load(InputStream inStream) 从输入流中读取属性列表
   public void store(OutputStream out,String comments) 将Properties对象中数据写入到文件中
3.加载配置文件的工具类
4.多线程
   并发:在同一时间段 执行两个或者多个操作 单核cpu交替执行(例子:一人吃两个包子)
   并行:在同一时刻   执行两个或者多个操作 多核cpu同时执行(例子:两人吃两个包子)
   进程:运行在内存中程序就是进程
   线程:通向cpu的执行的路径就是线程
   第一种创建方式:
      A.继承Thread
      B.重写run方法
      C.实例化线程对象
      D.调用开启线程的方法 start()
  常用的方法:
     A.获取线程名称 
        a. public final String getName()
        b.public static Thread currentThread() 获取当前线程
     B.设置线程名称
        a.public Thread(String name)
        b.public final void setName(String name)  
二、线程中常用方法 2.1 线程休眠
方法名称方法描述
public static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠

代码-线程类

package com.qf.test02;

public class MyThread extends  Thread {
    @Override
    public void run() {
        for (int i=15;i>0;i--) {
            System.out.println("还剩下"+i+"秒");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

代码-测试类

package com.qf.test02;

public class Test01 {
    public static void main(String[] args) {
        //实例化线程类
        MyThread th = new MyThread();
        th.start();
    }
}

2.2 守护线程
1.守护线程:守护其它的线程 守护其它线程执行操作 在java中gc就是守护线程 项目在运行中会产生很多垃圾
         这些垃圾都由gc默默在后台进行回收 gc就是一个守护线程
2.守护线程死亡:
   A.被守护线程执行完操作 
   B.被守护线程死亡 
3.守护线程一般是守护主线程
方法名称方法描述
public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程
public final boolean isDaemon()测试该线程是否为守护线程

代码-线程类

package com.qf.test03;

import java.io.*;

public class MyThread extends  Thread {
    @Override
    public void run() {
        //睡五秒钟
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            //实例化流对象
            OutputStream os = new FileOutputStream("5.txt");
            os.write(97);
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

代码-测试类

package com.qf.test03;

public class Test01 {
    public static void main(String[] args) {
        //实例化线程对象
        MyThread th = new MyThread();
        //将该线程设置为守护线程
        th.setDaemon(true);
        //获取是否为守护线程
        System.out.println(th.isDaemon());
        //开启线程
        th.start();

        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

2.3 线程的优先级

注意点:

A.线程的优先级范围是1-10 线程优先级默认值是5

2.3.1 常量
常量的名称常量说明
public static final int MAX_PRIORITY线程可以具有的最高优先级
public static final int MIN_PRIORITY线程可以具有的最低优先级
public static final int NORM_PRIORITY分配给线程的默认优先级

2.3.2 方法

注意点: 线程优先级越高 表示获取cpu的执行权越大 优先级越高 执行的概率越大

方法名称方法描述
public final void setPriority(int newPriority)更改线程的优先级
public final int getPriority()获取线程优先级

代码-线程类

package com.qf.test04;

public class MyThread extends  Thread {
    @Override
    public void run() {
        for (int i=1;i<=100;i++){
            System.out.println(getName()+"t"+i);
        }
    }
}

代码-测试类

package com.qf.test04;

public class Test01 {
    public static void main(String[] args) {
        //实例化第一个线程对象
        MyThread th01 = new MyThread();
        th01.setPriority(5);
        th01.start();
        //实例化第二个线程对象
        MyThread th02 = new MyThread();
        th02.setPriority(3);
        th02.start();
        //实例化第三个线程对象
        MyThread th03 = new MyThread();
        th03.setPriority(10);
        th03.start();
    }
}

2.4 线程第二种创建方式

步骤

A.定义一个类 实现 Runnable接口
B.实现run()方法
C.实例化线程对象Thread  构造方法中传递Runnable的实现类
D.调用线程开启方法 start()

代码-线程类

package com.qf.test05;

public class MyRunnable implements  Runnable {
    @Override
    public void run() {
        for (int i=0;i<=100;i++) {
            System.out.println(Thread.currentThread().getName()+"t"+i);
        }

    }
}

代码-测试类

package com.qf.test05;

public class Test01 {
    public static void main(String[] args) {
        //实例化Runnable实现类
        MyRunnable ru  = new MyRunnable();
        //实例化线程对象
        Thread th = new Thread(ru);
        //开启线程
        th.start();


        //实例化Runnable实现类
        MyRunnable ru1  = new MyRunnable();
        //实例化线程对象
        Thread th1 = new Thread(ru1);
        //开启线程
        th1.start();


    }
}

2.5 使用匿名内部类创建线程
package com.qf.test06;

public class Test01 {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }).start();

        new Thread(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }.start();

    }
}

三、线程通信 3.1 案例-需求

3.2 分析
A.三个窗口  可以使用三个线程
B.需要数据共享  实现Runnable接口
C.定义一个变量来记录100张票
D.一直买票 死循环 while(true)

3.3 代码

线程类

package com.qf.test07;

public class MyRunnable implements Runnable {
    //定义变量来记录100张票
    private int count = 100;

    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //一直买票
        while (true) {
            //有票才能售卖
            if (count > 0) {
                System.out.println(Thread.currentThread().getName() + "在出售第" + count + "票");
                //票数需要递减
                count--;
            }
        }

    }
}


测试类

package com.qf.test07;

public class Test01 {
    public static void main(String[] args) {
        //实例化MyRunnable
        MyRunnable run = new MyRunnable();

        //实例化第一个线程对象
        Thread  th01 = new Thread(run);
        th01.start();

        //实例化第二个线程对象
        Thread  th02 = new Thread(run);
        th02.start();

        //实例化第三个线程对象
        Thread  th03 = new Thread(run);
        th03.start();
    }
}


3.4 产生问题的原因

3.5 第一种解决方案-使用同步代码块
1.语法:
   synchronized(锁的对象) {
        可能产生数据共享安全问题代码
   }
2.说明:
   A.锁的对象可以是任意的对象
   B.所有的线程必须操作的是同一个锁对象
3.作用:
   解决多线程数据安全的问题

代码

package com.qf.test07;

public class MyRunnable implements Runnable {
    private int count = 100;
    //定义一个锁的对象
    private  Object  obj = new Object();
    @Override
    public void run() {


        while (true) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (obj) {
                 if (count > 0) {
                     System.out.println(Thread.currentThread().getName() + "在出售第" + count + "票");
                     count--;
                 }
             }
        }

    }
}


3.6 解决问题原因

3.7 第二种解决方案-同步方法
1.语法:
    访问修饰符 synchronized  返回值类型 方法的名称(参数列表) {
         方法体;
         return 返回值
    }
2.说明:
   A.synchronized 可以修饰普通成员方法  也可以修饰静态方法
3.注意点
    A.普通成员方法锁的对象是当前对象this
    B.静态方法锁的对象是当前对象的class对象

代码

package com.qf.test07;

public class MyRunnable implements Runnable {
    private static int count = 100;

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //showInfo();
           
           //showInfo();
            synchronized (MyRunnable.class){
                if (count > 0) {
                    System.out.println(Thread.currentThread().getName() + "在出售第" + count + "票");
                    count--;
                }
            }

        }

    }

 

   
}


3.8 第三种解决方案-Lock
1.Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构
2.实现类:ReentrantLock
3.方法

方法名称方法描述
void lock()获取锁对象
void unlock()释放锁

代码

package com.qf.test07;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyRunnable implements Runnable {
    private static int count = 100;
    //实例化锁对象
    private Lock  lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
             //获取锁对象
             lock.lock();
            try {
                Thread.sleep(50);
                if (count > 0) {
                    System.out.println(Thread.currentThread().getName() + "在出售第" + count + "票");
                    count--;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                //释放锁对
                lock.unlock();

            }


        }

    }


}


四、死锁
1.概念:死锁 A占用B锁的锁对象  B占用A锁对象 互不相让 两个线程处于等待状态 这样就出现了死锁
2.生活例子:
   阿飞与阿超同一个宿舍  宿舍中只有一双拖鞋  两个人都要出去买东西  阿飞抢到左拖鞋 阿超强到右拖鞋
   两人互不谦让  两人都出不去 死锁

代码-鞋子类

package com.qf.test08;

public class Shoe {
    //左拖鞋
    public  static  final  String LEFT="LEFT";
    //右拖鞋
    public  static  final  String RGIGHT="RGIGHT";
}


代码-MyRunnable01

package com.qf.test08;

public class MyRunnable01 implements  Runnable{

    @Override
    public void run() {
        synchronized (Shoe.LEFT){
            System.out.println("阿飞获取左拖鞋");
            synchronized (Shoe.RGIGHT) {
                System.out.println("阿飞获取右拖鞋");
            }
        }

    }
}


代码-MyRunnable02

package com.qf.test08;

public class MyRunnable02 implements  Runnable {
    @Override
    public void run() {
        synchronized (Shoe.RGIGHT){
            System.out.println("阿超获取右拖鞋");
            synchronized (Shoe.LEFT){
                System.out.println("阿超获取左拖鞋");
            }
        }

    }
}


代码-测试类

package com.qf.test08;

public class Test01 {
    public static void main(String[] args) {
        MyRunnable01  run01 = new MyRunnable01();
        //实例化线程对象
        Thread  th01 = new Thread(run01);
        //开启线程
        th01.start();

        MyRunnable02 run02 = new MyRunnable02();
        //实例化线程对象
        Thread th02  =new Thread(run02);
        th02.start();
    }
}


五、线程中常用方法
方法名称方法描述
public final void stop()终止线程(立刻线程中操作)
public static void yield()暂停当前正在执行的线程对象,并执行其他线程(礼让)
public final void join()等待该线程终止(这个方法必须在线程开启之后调用)
5.1 stop 方法演示

代码-线程类

package com.qf.test09;

public class MyThread extends  Thread {
    @Override
    public void run() {
        for (int i=1;i<=10;i++){
            if (i==5) {
               // stop();
                interrupt();
            }
            System.out.println(i);
        }
    }
}


代码-测试类

package com.qf.test09;

public class Test01 {
    public static void main(String[] args) {
        MyThread  th = new MyThread();
        th.start();
    }
}


5.2 yield() 方法演示

代码-线程类

package com.qf.test10;

public class MyThread extends  Thread {
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"t"+i);
        }
    }
}


代码-测试类

package com.qf.test10;

public class Test01 {
    public static void main(String[] args) {
        //实例化线程对象
        MyThread th01 = new MyThread();
        //礼让
        th01.yield();
        //开启线程
        th01.start();

        //实例化线程对象
        MyThread  th02  = new MyThread();
        th02.start();

    }
}


5.3 join() 方法演示

代码-线程类

package com.qf.test11;

public class MyThread extends  Thread {
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"t"+i);
        }
    }
}


代码-测试类

package com.qf.test11;

public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        //实例化线程对象
        MyThread th01 = new MyThread();
        //开启线程
        th01.start();
        th01.join();

        //实例化线程对象
        MyThread th02  = new MyThread();
        th02.start();

    }
}


六、Object提供操作线程的方法
方法的名称方法的描述
public final void wait(long timeout)计时等待
public final void wait()无线等待
public final void notify()唤醒在此对象监视器上等待的单个线程(唤醒一个)
public final void notifyAll()唤醒在此对象监视器上等待的所有线程
七、案例

代码

package com.qf.test12;

public class Test01 {
    public static void main(String[] args) {
        //定义一个锁对象
        Object obj = new Object();
        //李焕荣线程
        new  Thread(){
            @Override
            public void run() {
                synchronized (obj){
                    System.out.println("我需要一个包子");
                    //无线等待
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println("正在吃包子........");

                }
            }
        }.start();

        //老板线程
        new Thread(){
            @Override
            public void run() {
                synchronized (obj){
                    //花两秒钟做一个包子
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("已经做好了一个包子");
                    //通知李焕荣吃包子
                    obj.notify();
                }
            }
        }.start();
    }

}


八、多线程中生产者与消费者模式

step01 需求-分析

step01-生产者线程

package com.qf.test13;

public class MyThread01  extends  Thread {
    private  BaoZi baoZi;
    public  MyThread01(BaoZi baoZi){
        this.baoZi=baoZi;
    }
    @Override
    public void run() {
        //一直生产包子
        while (true){

            synchronized (baoZi) {
                //需要无线等待
                if (baoZi.flag) {
                    try {
                        baoZi.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                //生产一个包子
                baoZi.pi="薄皮";
                baoZi.xian="韭菜鸡蛋";
                System.out.println("生产一个"+baoZi.pi+"t"+baoZi.xian+"包子");
                //将标记设置为true
                baoZi.flag= true;
                //通知消费者进行消费
                baoZi.notify();
            }

        }
    }
}


step02-消费者线程

package com.qf.test13;

public class MyThread02 extends  Thread {
    private  BaoZi baoZi;

    public  MyThread02(BaoZi baoZi) {
        this.baoZi=baoZi;
    }

    @Override
    public void run() {
        //一直消费包子
        while (true){
            synchronized (baoZi){
                if (!baoZi.flag){
                    try {
                        baoZi.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                //消费包子
                System.out.println("消费了一个"+baoZi.pi+"t"+baoZi.xian+"的包子");
                baoZi.xian=null;
                baoZi.pi=null;
                //将标记设置为false
                baoZi.flag=false;
                //通知生产者生成包子
                baoZi.notify();
            }
        }

    }
}


step03 包子类

package com.qf.test13;

public class BaoZi {
    public String pi;
    public  String xian;
    public  boolean  flag = false; // 表示没有包子
}


step04-测试类

package com.qf.test13;

public class Test01 {
    public static void main(String[] args) {
        //实例化包子对象
        BaoZi baoZi = new BaoZi();
        //实例化生成者线程
        new  MyThread01(baoZi).start();
        //实例化消费者线程
        new MyThread02(baoZi).start();
    }
}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1039078.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号