线程3 + IO流

用户线程和守护线程:

  1. 用户线程:也叫工作线程,当线程的任务执行完或通知方式结束
  2. 守护线程:一般是为工作线程服务的,当所有的用户线程结束,守护线程自动结束
  3. 常见的守护线程:垃圾回收机制
将一个线程设置成守护线程:
public static void main(String[] args) {
    MyDaemonThread myDaemonThread = new MyDaemonThread();
    //如果希望当main线程结束后,子线程自动结束
    //只需将子线程设置为守护线程即可
    myDaemonThread.setDeamon(true);
    //先设置好守护线程,再start
    myDaemonThread.start();
    for (int i = 1;i <= 10 ; i++) { //主线程
        System.out.print("工作中~~~~~~");
        Thread.sleep(1000);
    }
}

class MyDaemonThread extends Thread{
    public void run(){
        for (; ; ) {    //无限循环
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            System.out.print("哈哈哈哈哈~~~~~");
        }
    }
}

线程的生命周期:

线程7大状态:
  1. NEW:尚未启动的线程处于此状态
  2. RUNNABLE:在java虚拟机中执行的线程处于此状态
  3. BLOCKED:被阻塞等待监视器锁定的线程处于次状态
  4. WAITING:正在等待另一个线程执行特定动作的线程处于此状态
  5. TIMED_WAITING:正在等待另一个线程执行动作达到指定时间的线程处于此状态
  6. TERMINATED:已退出的线程处于此状态

线程同步机制:

  1. 在多线程编程,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何同一时刻,最多有一个线程访问,以保证数据的完整性。
  2. 也可以这样理解:线程同步,即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作
同步具体方法- Synchronized:
  1. 同步代码块:

    synchronized(对象){ //得到对象的锁,才能操作同步代码
    //需要被同步的代码
    }

  2. synchronized还可以放在方法声明中,表示整个方法-为同步方法

    public synchronized void m(String name){
    //需要被同步的代码
    }

    //实现接口的方式,使用synchronized实现线程同步
    class SellTicket02 implements Runnable{
    private int ticketNum = 100; //让多个线程共享ticketNum
    private boolean loop = true;

    //1、public synchronized void sell(){} 就是一个同步方法
    //2、这时锁在this对象
    //3、也可以在代码块上写synchronize,同步代码块,互斥锁还是在this对象
    public /synchronized/ void sell(){ //同步方法,在同一时刻,只能有一个线程来执行sell方法
    synchronized (this){ //同步代码块
    if (ticketNum <= 0) {
    System.out.print(“售票结束“);
    loop = false;
    return ;
    }
    //休眠50毫
    try{
    Thread.sleep(50);
    }catch(InterruptedException e){
    e.printStackTrace();

    System.out.print("窗口" + Thread.currentThread().getName() 
        + "售出了一张票" + "剩余票数" + (--ticketNum));
    

    }

    }
    @Override
    public synchronized void run(){
    while(loop){
    sell();
    }
    }

互斥锁:

  1. Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性

  2. 每个对象都对应于一个可称为”互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象

  3. 关键字synchronized来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任意时刻只能由一个线程访问

  4. 同步的局限性:导致程序的执行效率要降低

  5. 同步方法(非静态的)的锁可以是this,也可以是其他对象(要求是同一个对象)

  6. 同步方法(静态的)的锁为当前类本身

    //同步方法(静态的)的锁为当前类本身
    //1、public synchronized static void m1(){} 锁是加载类上的 XX.class
    public synchronized static void m1(){
    }

    //2、如果在静态方法中,实现一个同步代码块
    public static void m2(){
    synchronized (XX.class){
    System.out.print(“m2”);
    }
    }

注意:
  1. 同步方法如果没有使用static修饰:默认锁对象为this
  2. 如果方法使用static修饰,默认锁对象:当前类.class
  3. 实现的落地步骤:
    1. 需要先分析上锁的代码
    2. 选择同步代码块或同步方法
    3. 要求多个线程的锁对象为同一个即可

线程的死锁:

多个线程都占用了对方的锁资源,但不肯相让,导致了死锁,,在编程时一定要避免死锁的发生

释放锁:

下面操作会释放锁:
  1. 当前线程的同步方法、同步代码块执行结束

​ 案例:上厕所,完事出来

  1. 当前线程在同步代码块、同步方法中遇到break、return

​ 案例:没有正常的完事,被叫出来修bug,不得已出来

  1. 当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致异常结束

​ 案例:没有正常的完事,发现忘带纸,不得已出来

  1. 当前线程在同步代码块、同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁

​ 案例:没有正常完事,觉得需要酝酿下,所以出来等会再进去

下面操作不会释放锁:
  1. 线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法暂停当前线程的执行,不会释放锁

​ 案例:上厕所,太困了,在坑位上眯了一会

  1. 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁

​ 提示:应尽量避免使用suspend()和resume()来控制线程,方法不再推荐使用

文件流:

文件在程序中是以流的形式来操作的

流:
  • 数据在数据源(文件)和程序(内存)之间经历的路径
输入流:
  • 数据从数据源(文件)和程序(内存)的路径
输出流:
  • 数据从程序(内存)到数据源(文件)的路径

常用的文件操作:

创建文件对象相关构造器和方法:
    new File(String pathname)   //根据路径构建一个File对象
    new File(File parent,String child)  //根据父目录文件+子路径构建
    new File(String parent,String child)    //根据父目录+子路径构建

    creatNewFile    创建新文件
例:

请在e盘下,创建文件 news1.txt news2.txt news3.txt,用3中不同方式创建

    //方式一
    public void create01(){
        System filePath = "e:\\news1.txt";
        File file = new File(filePath);
        file.creatNewFile();
    }

    //方式二    根据父目录文件+子路径构建
    //e:\\news2.txt
    public void create02(){
        File parentFile = new File("e:\\");
        String fileName = "news2.txt"
        //只有执行了creatNewFile方法,才会真正的在磁盘创建该文件
        File file = new File(filePath);
        file.creatNewFile();
    }

    //方式三 根据父目录+子路径构建
    public void create03(){
        String parentPath = "e:\\";
        String fileName = "news3.txt";
        File file = new File(parentPath,fileName);

        file.creatNewFile();
    }
获取文件信息:
  1. getName

  2. getAbsolutePath

  3. getParent

  4. length

  5. exists

  6. isFile

  7. isDirectory

    public void info(){
    //先创建文件对象
    File file = new File(“e:\news1.txt”);

    //调用相应的方法,得到对应信息
    System.out.print("文件名字" + file.getName());
    System.out.print("文件绝对路径" + file.getAbsolutePath());
    System.out.print("文件父级目录" + file.getParent());
    System.out.print("文件大小(字节)" + file.length());
    System.out.print("文件是否存在" + file.exists());
    System.out.print("是不是一个文件" + file.isFile());
    System.out.print("是不是一个目录" + file.isDirectory());
    

    }

创作不易!转载请注明作者及文章链接或作者博客链接——
- 作者:pidanxia
- 链接:https://pidanxia.ink
(链接可为:**文章链接**或者**作者博客链接**)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇