博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java-多线程
阅读量:2444 次
发布时间:2019-05-10

本文共 6543 字,大约阅读时间需要 21 分钟。

Java多线程:java语言的一个优势就是处理多线程简单

    在一个操作系统中会同时运行多个任务(程序),例如:QQ、微信等
    1.在操作系统中同时运行的每一个任务都是一个进程
    2.对于一个进程(程序)而言,在程序内部也会同时运行多个任务,那个每一个任务称为一个线程
    
    线程的运行都是并发执行的,所谓的并发:宏观上所有的线程都是同时执行的,但是微观上所有的线程都是"走走停停"
    
    线程的调度:
    将CPU的时间划分为若干个时间片段,尽可能的均匀分配给每一个线程,获得CPU时间片段的线程将得以CPU执行
    
    创建线程的两种方式:Thread类  线程类
    其每一个实例表示一个可以并发的线程(匿名内部类)
    使用线程的注意事项:
    对于线程调度而言,分配的时间片段长短,具体分配给哪一个线程时间片段,对于程序而言,都是不可控制的
        * 使用多线程不考虑执行的先后顺序问题
        * 执行没有先后顺序的是异步运行(并发运行)--登录
        * 执行有先后顺序的是同步运行--银行取钱
        
    第一种创建线程的方式:继承Thread类
        第一种创建线程的方式存在弊端:
         * 线程与线程要干的事情(任务)耦合在一起
        * --启动线程是调用start方法,自动执行run方法
        *继承只能单继承
        
    第二种创建线程的方式:实现Runnable接口
        --将任务和线程解耦

    线程在执行某段逻辑时可以发生阻塞现象(控制自己不被执行)

    sleep阻塞:
    该阻塞可以指定阻塞时间,并在线程阻塞了该时间后自动返回runnable等待方法,Thread提供了一个静态方法sleep()用于睡眠阻塞
    
    线程阻塞在以下情况可以停止:
    1、run方法正常执行完毕
    2、run方法执行过程中抛出了一个未捕获的异常
    
    进程的停止:
    当一个进程中所有前台线程停止后,该进程结束
    
    前台线程和后台线程
    后台线程的特点:用法与前台线程无异,只是当一个进程中所有前台线程都结束后,
    无论后台线程是否还在运行中都被强制结束,从而使得进程结束,程序退出
    后台线程:也称为守护线程,或者精灵线程---lol开挂刷野时间盒
设置后台线程
    设置后台线程方法要在该线程被调用start()之前调用
    zhou.setDaemon(true);
    
    在运行我们的程序时,操作系统会启动一个进程来运行JVM,JVM运行后会创建第一个前台
    线程来运行我们的程序的main方法,同时也会创建一个后台线程来运行GC(垃圾回收机制)

线程的优先级:1-10(1最低、10最高)

    优先级越高的线程被分配时间片段的机会就越多,那么CPU执行的机会就越多
    
    线程安全:
    多线程并发访问同一资源时,会产生线程安全问题
    解决办法:并发即异步---将异步操作变成同步操作
    1、多线程并发读写同一临界资源会发生“线程安全并发问题”
        如果保证多线程同步访问临界资源,就可以解决安全问题。
    2、常见的临界资源:
        多线程共享的实例变量、静态的公共变量
    3、异步:各干各的  执行没有先后顺序      AJax
       同步:你干完我再干    执行有先后顺序
    4、同步锁:关键字synchronized----重要!!!
        synchronized可以修饰方法,当一个方法被修饰后,这个方法就是同步方法,同一刻只有一个线程访问该方法
    synchronized块
    当一个方法被修饰后,该方法变成同步方法,虽然保证了代码的执行安全,但是效率
    低下,我们实际上只需要将方法需要的同步片段加锁,这样可以缩小同步范围,从而
    提高代码的运行效率
    语法:
    synchronized(同步监视器){
        需要同步的代码片段
    }
    同步监视器:就是一个对象,任何对象都可以,可以new Object()
    但要保证一点,多线程看到的应该是"同一个"对象,通常情况下使用this

    非线程安全             线程安全

    StringBuilder        StringBuffer
    ArrayList            Vector
    HashMap              HashTable
    HashSet   ......
    对于集合Collection和Map而言
    Collections类提供了可以将给定的集合转换为线程安全的集合方法    
    list = Collections.synchronizedList(list);

    线程的协调工作:

    download.join();  //先执行download线程
    
    wait-notify
        使用wait()和notify()完成线程的协同工作
         * wait()阻塞会在以下两种情况被解除
            * 1.当download线程结束
            * 2.当调用了download的notify()
         * ---属于Object方法
                synchronized(object){
                object.wait();
        synchronized(object){
        //通知object身上的等待的线程解除阻塞
        object.notify();
        }

Day05

总结--创建线程的方式:
    1、继承Thread类
        实体类继承Thread类,覆盖run()方法,提供并发运行的过程
        创建这个类的实例    使用start()启动线程
    2、实现Runnable接口
    3、使用内部类/匿名内部类创建线程
    
线程的状态
    1、new 新建状态,还未启动
    
    2、Runnable    等待状态,可以运行状态(就绪)
    
    3、Ruuning    正在运行的状态,该线程已经获得了CPU
        a.假设线程获取了CPU,则进入Running状态,开始执行线程体
        
        b.假设系统只有一个CPU那么在任意时间点,只有一个线程属于Running
            如果是双核,那么在同一时间点,那么会有两条线程处于Running,但是当线程数大于处理器,依然会是多条线程在同一CPU轮换执行
            
        c.当一条线程开始运行的时候,如果不是一瞬间完成,那么它不可能一直处于
            Running状态,线程会在执行过程中被中断,目的是为了让其他线程获得执行机会,像这样的线程调度的策略取决于底层平台,对于抢占式策略的平台来说,
            系统会给每个可执行的线程一小段时间来处理任务,当该时间片段用完了,系统会剥夺线程所占资源(CPU),让其他线程获得运行机会
            
    4、block  阻塞或者挂起状态
        a.以下情况会发生阻塞状态
            1.线程使用了sleep()
            2.线程调用了阻塞式IO方法(比如控制台输入方法),在该方法放回前,该线程被阻塞
            3.join  wait-notify
        b.当正在执行的线程被阻塞时,其他线程就获得机会,阻塞结束的时候,该线程
            进入Runnable等待状态,而非直接进入Running状态
            
    5、dead    死亡状态
        run()执行结束,该线程进入死亡状态,不要试图对一个已经死亡的线程调用
        start(),死亡后不能再次作为线程执行,会抛出异常
    
线程的状态管理:
    1、Thread.sleep(times)
        使当前线程从Running放弃处理器进入block状态,休眠times毫秒,再返回Runnable状态,如果其他线程打断了当前线程的Block(sleep)
        就会发生中断异常InterruptedException
    2、Thread.yield()
        让出CPU,当线程让出处理器(离开Running),进入Runnable状态
        
线程的常用属性和方法:
    1.线程的优先级
        setPriorty
    2.后台线程(守护线程)
        线程对象引用名.setDaemon(true)
    3.获取线程的名字
        getName()
    4.获取当前线程
        Thread.currentThread()
    5.sleep状态的打断和唤醒
        Thread.sleep(times)
        引用名.interrupt()    被唤醒的线程会出现中断异常
        
线程池:Java1.5提供了并发包concurrent
    Executors是工厂,包含工厂用于创建Executor接口的实例
    Executor threadPools=Executors.newFixedThreadPool(2);
    Process p1=new Process();
    threadPools.execute(p1);//执行

创建线程的两张方式:

package day04;//第一种创建线程的方式:继承Thread类public class ThreadDemo01 {	public static void main(String[] args) {		Thread t1=new Person1();		Thread t2=new Person2();		//启动线程是调用start方法,自动执行run方法		t1.start();		t2.start();		/*		 * 使用多线程不考虑执行的先后顺序问题		 * 执行没有先后顺序的是异步运行(并发运行)--登录		 * 执行有先后顺序的是同步运行--银行取钱		 */	}	/*	 * 第一种创建线程的方式存在弊端:	 * 线程与线程要干的事情(任务)耦合在一起	 * --启动线程是调用start方法,自动执行run方法	 */}class Person1 extends Thread{	public void run(){		for(int i=0;i<1000;i++){			System.out.println("你是谁啊");		}	}}class Person2 extends Thread{	public void run(){		for(int i=0;i<1000;i++){			System.out.println("我是收电费的");		}	}}

 

package day04;//第二种创建线程的方式:实现Runnable接口//将任务和线程解耦public class ThreadDemo02 {	public static void main(String[] args) {		//创建线程时再将任务指派		Thread t1=new Thread(new PersonOne());		Thread t2=new Thread(new PersonTwo());		t1.start();		t2.start();	}}class PersonOne implements Runnable{	public void run(){		for(int i=0;i<1000;i++){			System.out.println("你是谁啊");		}	}}class PersonTwo implements Runnable{	public void run(){		for(int i=0;i<1000;i++){			System.out.println("查水表的");		}	}}

 多线程Join:

package day04;//线程的协调工作public class JoinThreadDemo {	//图片是否下载完毕	public static boolean isFinish = false;	public static void main(String[] args) {		//下载图片的线程		final Thread download = new Thread(){			public void run(){				System.out.println("download:开始下载图片");				for(int i=0;i<=100;i++){					System.out.println("download:已完成"+i+"%");					try {						Thread.sleep(50);					} catch (Exception e) {						e.printStackTrace();					}				}				System.out.println("download:图片下载完毕");				isFinish = true;//表示图片下载完毕			}		};		//显示图片的线程		Thread showImg = new Thread(){			public void run(){				System.out.println("showImg:准备显示图片");				//等待下载线程工作结束后,再执行下面的代码				try {					//先执行download					download.join();				} catch (Exception e) {					e.printStackTrace();				}				if(!isFinish){					throw new RuntimeException("图片没有下载完毕");				}				System.out.println("showImg:图片已经显示了");			}		};		showImg.start();		download.start();			}}

多线程wait()...notify()

package day05;//使用wait()和notify()完成线程的协同工作public class WaitAndNotifyDemo {		public static boolean isFinish = false;		public static Object object=new Object();		public static void main(String[] args) {			//下载图片的线程			final Thread download = new Thread(){				public void run(){					System.out.println("download:开始下载图片");					for(int i=0;i<=100;i++){						System.out.println("download:已完成"+i+"%");						try {							Thread.sleep(50);						} catch (Exception e) {							e.printStackTrace();						}					}					System.out.println("download:图片下载完毕");					isFinish = true;//表示图片下载完毕					synchronized(object){						//通知object身上的等待的线程解除阻塞						object.notify();					}				}			};			//显示图片的线程			Thread showImg = new Thread(){				public void run(){					System.out.println("showImg:准备显示图片");					//等待下载线程工作结束后,再执行下面的代码					try {						/*						 * wait()阻塞会在以下两种情况被解除						 * 1.当download线程结束						 * 2.当调用了download的notify()						 * ---属于Object方法						 */						synchronized(object){							object.wait();						}											} catch (Exception e) {						e.printStackTrace();					}					if(!isFinish){						throw new RuntimeException("图片没有下载完毕");					}					System.out.println("showImg:图片已经显示了");				}			};			download.start();			showImg.start();		}			}

 

转载地址:http://wgpqb.baihongyu.com/

你可能感兴趣的文章
windows隐藏文件夹_在Windows中隐藏或密码保护文件夹的最佳方法
查看>>
macos 虚拟镜像文件_如何在macOS中使用虚拟文件测试网络或硬盘速度
查看>>
FAT32,exFAT和NTFS有什么区别?
查看>>
扔旧被子扔掉霉运_您应该扔掉所有高科技产品盒吗?
查看>>
cardboard下载_如何在Android上设置Google Cardboard
查看>>
如何在充电时阻止Nintendo Switch接管电视
查看>>
assistant字体_如何自定义您的Google Assistant每日简报
查看>>
失物招领php_我的Mac上“失物招领”文件夹中的大型iNode文件是什么?
查看>>
safari隐私模式_如何优化Safari以获得最大的隐私
查看>>
mozilla rhnio_如何优化Mozilla Firefox以获得最大的隐私
查看>>
macos减少磁盘写入_如何减少macOS Finder的吸附
查看>>
vim macos_如何在Linux(或macOS)上使用Vim密码保护文本文件
查看>>
facebook 个人账户_如何使人们更难找到您的Facebook帐户
查看>>
Google Chrome中的chrome:// plugins发生了什么?
查看>>
unas plex使用_如何在没有Internet访问的情况下使用Plex Media Server
查看>>
android wi-fi_如何在Android中关闭公共Wi-Fi通知
查看>>
windows网络文件共享_如何查看谁在Windows 8中从网络共享中下载文件
查看>>
linux gnome_在Gnome中学习这些鼠标技巧,以获得更高效的Linux体验
查看>>
打印机疑难解答_使用内置电源疑难解答改善Windows 7中的电池寿命
查看>>
为什么使用Google Chrome浏览器时网站文本大小突然增加?
查看>>