zoukankan      html  css  js  c++  java
  • java基础笔记(8)

    java的多线程

    进程:程序的执行过程,持有内存资源

    线程:是系统的最小执行单元,共享进程的资源

    线程之间可以互斥、也可以同步;

    Thraed类:

    通过一个案例来了解线程Thread类和Runnable接口的运用:

    案例须知:

    1、实现舞台线程(继承Thread类)

    2、实现军队线程,通过调用军队线程实现农民和政府双军队线程,将军队交战线程放到舞台线程中开始运行,双线程是交叉运行;(继承Runnable接口)

    3、实现一个英雄进场线程(继承Thread类),在双线程结束后将英雄入场线程放到舞台线程中运行,运行后结束后舞台线程随之结束;

    军队线程:

    package com.thread;
    
    public class Army implements Runnable {
        volatile boolean keepRunning =true;//保证了线程可以读取其他线写入的值
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(keepRunning) {
                for(int i = 0;i<5;i++) {
                    System.out.println(Thread.currentThread().getName()+"进攻对方["+i+"]次");
                    Thread.yield();//让出处理器时间,下次进攻是谁还不一定呢
                }
            }
            System.out.println(Thread.currentThread().getName()+"结束了战斗");
        }
    
    }

    英雄进场线程:

    package com.thread;
    
    public class Hero extends Thread {
        public void run() {
            System.out.println(Thread.currentThread().getName()+"加入了战斗");
            for(int i = 0;i<10;i++) {
                System.out.println(Thread.currentThread().getName()+"释放技能:“捞人自捞”");
                
            }
            System.out.println(Thread.currentThread().getName()+"结束了战斗");
        }
    }

    舞台线程:

    package com.thread;
    
    public class Stage extends Thread {
        public void run() {
            Army armyOfZf = new Army();
            Army armyOfNm = new Army();
            Thread armyOfZfTh = new Thread(armyOfZf,"政府");
            Thread armyOfNmTh = new Thread(armyOfNm,"农民");
            armyOfNmTh.start();
            armyOfZfTh.start();
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            armyOfZf.keepRunning = false;
            armyOfNm.keepRunning = false;
            Thread mrya = new Hero();
            mrya.setName("余桉");
            System.out.println("农民和政府打的不可开交时"+mrya.getName()+"冲入了战场!!!");
            try {
                Thread.sleep(50);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            mrya.start();
            try {
                mrya.join();//等待mrya线程运行完后,程序才会继续执行;
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {
                armyOfNmTh.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Stage test = new Stage();
            test.start();
        }
    
    }

    注意:这里的案例我们停止线程是用了一个一个布尔值keepRunning,将改变其值使得线程运行完毕,而java本身的Thread类有提供一个stop()的线程停止方法,但这个方法是不正确的停止方法,因为这个是“猝死”类型的停止方法,会让线程直接停止,这样会使得我们没法输出提示信息,也没能有效地处理线程的后=后续清理工作;因此说这个方法是不正确的停止方法;

    两个线程发生争用条件:两个不同的线程同时访问同一资源,在线程一把原本的资源改了,但是资源并没来得及传入硬盘而是只存在于内存中,此时若是切换到线程2.线程二对该资源操作完成后又切换到线程一,线程一继续刚没结束的上下文,把刚修改存在内存中的资源一再返回硬盘中,此时就会使得线程二对于资源的操作修改被覆盖,导致资源的状态和我们想要的不一样;

    线程互斥和同步:互斥即对线程进行加锁,需等线程解锁后别的线程才可以操作该共享对象;同步是指线程对共享对象的使用,需要让其共享资源满足于什么条件下才可以使用,此时线程会调用wait()方法进入等待,等别的线程操作完共享对象,达到该条件后再触发notifyAll(),唤醒等待状态的所有线程;

    先创建一个共享对象:

     线程开始之前:

    通过synchronized关键字定义临界端,wait()使得线程进入等待阶段,在Wait set集合中进行等待,别的线程可以进入这个临界端,当运行notifyAll()时唤醒所有线程;

  • 相关阅读:
    Golang的演化历程
    优秀的计算机编程类博客和文章
    NET Portability Analyzer
    NET SqlClient
    Razor模板引擎
    js资源
    依赖注入和控制器
    Vue.js 2.0 和 React、Augular
    过滤器
    Prism vs MvvmCross
  • 原文地址:https://www.cnblogs.com/lzj-learn/p/11868663.html
Copyright © 2011-2022 走看看