zoukankan      html  css  js  c++  java
  • Java基础——多线程

    1.线程的创建:

      方式一:继承java.lang.Thread类
      方式二:通过实现的方式

      继承的方式 VS 实现的方式:
        1.联系:public class Thread implements Runnable
        2.实现的方式优于继承的方式
          1.避免了Java单继承的局限性
          2.如果多个线程要操作同一份资源(或数据),更适合使用实现的方式

    package test;
    
    //创建线程的第一种方式:继承java.lang.Thread类
    //1.创建一个继承Thread的子类
    class SubThread extends Thread {
    	//2.重写run()方法,方法内实现此子线程要完成的任务
    	public void run() {
    		for(int i = 0; i < 100; ++i) {
    			System.out.println(Thread.currentThread().getName() + ": " + i);
    		}
    	}
    }
    public class TestThread {
    	public static void main(String[] args) {
    		//3.创建一个子类的对象
    		SubThread st = new SubThread();
    		//4.调用线程的start()方法:启动此线程;并且调用相应的run()方法
    		//一个线程只能执行一次start();
    		//不能通过直接调用Thread实现类对象的run()方法去启动一个线程 st.run();//错误的,相当于主线程内启动的
    		st.start();
    		
    		for(int i = 0; i < 100; ++i) {
    			System.out.println(Thread.currentThread().getName() + ": " + i);
    		}
    	}
    	
    }
    

      

    package test;
    //创建线程的第二种方式:通过实现的方式 //1.创建一个实现了Runnable接口的类 class SubThread1 implements Runnable{ //2.实现接口的抽象方法 public void run() { //子线程执行的代码 for(int i = 0; i < 50; ++i) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } public class TestThread1 { public static void main(String[] args) { //3.创建一个Runnable接口实现类的对象 SubThread1 p = new SubThread1(); //要想启动多线程,必须调用start() //4.将此方法作为形参传递给Thread类的构造器中,创建Thread类的对象,此对象即为一个线程 Thread t1 = new Thread(p); //5.调用start()方法,启动线程并执行run() t1.start(); //再创建一个线程 Thread t2 = new Thread(p); //不用再重新创建p,直接传入Thread即可 t2.start(); } }

    2.Thread的常用方法:
      1.void start(): 启动线程,并执行对象的run()方法
      2.run(): 线程在被调度时执行的操作
      3.String getName(): 返回线程的名称
      4.void setName(String name):设置该线程名称
      5.static currentThread(): 返回当前线程
      6.static void yield():线程让步 调用此方法的线程释放当前CPU的执行权
      7.join() :A线程中调用B线程的join()方法,表示:当执行到此方法,A线程停止执行,知道B线程执行完毕,A线程再接着join()之后的代码执行
      8.static void sleep(long millis):(指定时间:毫秒) 不会释放锁
        令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。
        抛出InterruptedException异常
      9.stop(): 强制线程生命期结束
      10.boolean isAlive():返回boolean,判断线程是否还活着
      11.线程通信:wait()(会释放锁) notify() notifyAll()

    3.设置线程的优先级:(1 - 10)
      MAX_PRIORITY(10);
      MIN _PRIORITY (1);
      NORM_PRIORITY (5);
      涉及的方法:
        getPriority() :返回线程优先值
        setPriority(int newPriority) :改变线程的优先级
      

      注:线程创建时继承父线程的优先级

    多线程程序的优点:
      提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
      提高计算机系统CPU的利用率
      改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改


    线程安全:多线程中,存在共享数据
      由于一个线程在操作共享数据过程中,未执行完毕的情况下,另外的线程参与进来,导致共享数据存在了安全问题
      解决:必须让一个线程操作共享数据完毕后,其他线程才有机会参与共享数据的操作

    4.线程的同步机制:解决线程安全问题
      方式一:同步代码块 保证所有线程共用同一把锁
        synchronized(同步监视器:即锁){
          //需要被同步的代码块(即为操作共享数据的代码)
        }
        1.共享数据:多个线程共同操作的同一个数据(变量)
        2.同步监视器(锁):可以由任何一个类的对象来充当。哪个线程获取此监视器,谁就执行大括号里被同步的代码。俗称:锁
          可以这样 Object obj = new Object; (把obj放进去都可以),但是不能是局部变量(不能放在run方法内)

      注:所有线程共用同一个锁,在实现的方式中,考虑同步的话,可以使用this来充当锁。
        但是在继承方式中,慎用this(因为会创建多个对象,this每次指代的不是同一个对象)static Object obj = new Object;
        对于静态方法而言,使用当前类本身充当锁(Singleton.class)


      方式二:同步方法 public synchronized void show(){//操作共享数据的代码}
        将操作共享数据的部分封装为一个方法,且声明为synchronized,即此方法为同步方法,能够保证当其中一个线程执行此方法时,其他线程在外等待,直至此线程执行完此方法
        1.对于非静态方法,同步方法的锁:默认为this。如果使用继承的方式实现多线程,慎用
        2.对于静态方法,如果使用同步,默认锁为:当前类本身 以单例的懒汉式为例,Class clazz = Singleton.class

    线程同步的弊端:由于同一时间只能有一个线程访问数据,效率变低了。

    释放锁的操作:wait()
      当前线程的同步方法、同步代码块执行结束
      当前线程在同步代码块、同步方法中遇到break、return终止了该代码块、该方法的继续执行。
      当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致异常结束
      当前线程在同步代码块、同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁。
    不会释放锁的操作:sleep()、yield()、suspend()
      线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法暂停当前线程的执行
      线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁(同步监视器)。
      应尽量避免使用suspend()和resume()来控制线程

    死锁:

    线程通信:wait() 与 notify() 和 notifyAll()
      wait():令当前线程挂起并放弃CPU、同步资源,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问
      notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
      notifyAll():唤醒正在排队等待资源的所有线程结束等待.

    注:Java.lang.Object提供的这三个方法
    只有在synchronized方法或synchronized代码块中才能使用,否则会报java.lang.IllegalMonitorStateException异常

  • 相关阅读:
    第十章 嵌入式Linux的调试技术
    第九章 硬件抽象层:HAL
    第八章 让开发板发出声音:蜂鸣器驱动
    第八章GPS与Google Map定位系统
    第六章 接口驱动程序开发
    第七章 Android嵌入式组态软件
    第五章 S5PV210硬件结构
    第四章
    第三章
    第二章
  • 原文地址:https://www.cnblogs.com/SkyeAngel/p/7811966.html
Copyright © 2011-2022 走看看