【我的Java笔记】多线程_多线程的概述 & 实现方式

来源:互联网 发布:淘宝宝贝原价和折扣价 编辑:程序博客网 时间:2024/06/05 09:59

进程

1.进程的概念:

正在运行的程序。进程是系统分配资源调用的一个独立单位


2.多进程的意义:

(1)计算机在做一件事情的同时还可以做另一件事

(2)为了提高CPU的使用率


3.多进程:两个程序之间并不是同时进行,而是由CPU的一点点时间片在两者之间的高效切换





线程


1.线程是依赖于进程存在,一个线程相当于进程中的某个任务


2.线程的概念:

(1)多线程:一个程序的执行路径有多条

(2)单线程:一个程序的执行路径只有一条


3.多线程的意义:

一个进程中开启了多个任务,每一个任务(线程)在互相抢占CPU的执行权(可以提高执行效率

4.多线程的特点:线程的执行具有随机性


注:Java虚拟机JVM是多线程程序吗?

是多线程程序,Java虚拟机自带垃圾回收器,来确保程序不会轻易造成内存溢出

(1)主线程:当前程序在执行代码时,开启main方法

(2)子线程:垃圾回收器


5.进程和线程的关系:线程的实现需依赖于一个进程的创建


6.并发和并行的概念:

(1)并发:指的是同一个时间点

(2)并行:指的是一个时间段


7.线程的生命周期图解:





多线程的实现方式

*方式1:
(1)自定义一个类,继承自Thread类
(2)自定义类重写Thread类中的 run() 方法
(3)在主线程(main)中,创建该类的实例对象,启动线程





*方式2:
 通过构造方式:public Thread (Runnable target , String name)
(1)自定义一个类,该类实现 Runnable 接口
(2)实现接口中的 run() 方法
(3)在主线程中创建该类的实例对象
(4)创建Thread对象,将步骤(3)的对象做为参数传递
(5)分别启动线程 





*方式3:
多线程实现的第三种方式:线程池
(详见博客《多线程的第三种实现方式(线程池)》)





问题:为什么有了第一种创建线程的的方式,还要第二种接口的方式?
答:第一种方式使用了继承的方式,而单继承具有局限性。
而第二种方式更符合Java的设计原则以及设计模式:数据分离原则
MyRunnable对象作为两个子线程的共有对象(共享数据),Java中多线程实现方式接口多一些






Thread类(实现Runnable接口)

1.Thread类中的构造方式:

(1)public Thread () 分配新的Thread对象

(2)public Thread (Runnable target , String name)参数一为Runnable接口对象


注:run() 方法内执行的都为耗时操作(耗时操作:线程等待、线程睡眠、循环语句)


2.Thread成员方法:

(1)public void start()使该线程开始执行,Java 虚拟机调用该线程的 run 方法

注:线程若启动结束后不能再启动,第二次启动会出现非法线程状态异常

(2)public void run()Thread的子类重写此方法,由Java虚拟机调用

注:run() 不能启动线程,run() 为一个普通的方法,并不会出现线程的随机性,而start() 方法调用其实是通过JVM调用线程中的run() 来进行多个线程抢占CPU的执行权(线程之间互相抢占)

(3)public static Thread currentThread()返回对当前正在执行的线程对象的引用

①线程的命名和获取方法:

(1)public final void setName(String name)改变线程名称,使之与参数 name 相同

(2)public final String getName()返回该线程的名称

②线程的优先级:

(1)public final int getPriority()返回线程的优先级

(2)public final void setPriority(int newPriority)更改线程的优先级

注:线程的优先级默认=5,最大优先级=10,最小优先级=1

(线程的执行具有随机性,虽然确定了优先级,但优先级只是概率事件,优先级大则抢到执行权的概率大)

③线程的停止:

(7)public final void stop()强迫线程停止执行

注:此方法线程会强行停止,不会再执行下面的操作
(8)public void interrupt()中断线程

注:中断标记,只是一种状态,下面的线程还会执行

④join和yieid方法:

(1)public static void yield()暂停当前正在执行的线程对象,并执行其他线程

注:几个线程之间换着执行,如线程1,线程2,线程1,线程2······(该方法不受优先级影响)
(2)public final void join()等待该线程终止

注:放置于线程执行之后,如:线程1.start();线程1.join();线程2.start;则线程1先执行完结束之后才会执行线程2


⑤线程的睡眠:

(1)public static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)


⑥守护线程:

(1)public final void setDaemon(boolean on)当参数为true时,设置为守护线程

注:该方法必须在 start() 开始之前调用,当主线程完成后,守护线程过段时间也会自己消亡(并不会在主线程结束之后立即消亡)

撒打算






一、多线程的第一种实现方式


例1:线程命名的两种方式

public class ThreadDemo {public static void main(String[] args) {// 线程命名方式1:通过自定义类的有参构造MyThread my1 = new MyThread("线程1");MyThread my2 = new MyThread("线程2");my1.start();my2.start();// 线程命名方式2:通过无参构造+setName(String name)方法MyThread my3 = new MyThread();MyThread my4 = new MyThread();my3.setName("线程3");my4.setName("线程4");my3.start();my4.start();}}class MyThread extends Thread {public MyThread() {}public MyThread(String name) {super(name);}@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(getName() + ":" + i);}}}





例2:更改线程的优先级 setPriority(int newPriority)

public class ProrityDemo {public static void main(String[] args) {// 创建该线程的实例MyPriority mp1 = new MyPriority();MyPriority mp2 = new MyPriority();MyPriority mp3 = new MyPriority();// 设置线程名称:无参构造+setName()方法mp1.setName("伊卡尔迪");mp2.setName("佩里西奇");mp3.setName("汉达诺维奇");// 给线程设置优先级mp1.setPriority(10);mp2.setPriority(1);mp3.setPriority(7);// 启动线程mp1.start();mp2.start();mp3.start();}}// 自定义的线程类class MyPriority extends Thread {@Overridepublic void run() {for (int x = 0; x < 5; x++) {System.out.println(getName() + ":" + x);}}}




注:此种方法虽然设置了优先级,但优先级只是概率事件,线程的执行基友随机性







例3:join() 等待线程终止

public class JoinDemo {public static void main(String[] args) {// 创建该线程的实例对象JoinThread jt1 = new JoinThread();JoinThread jt2 = new JoinThread();JoinThread jt3 = new JoinThread();// 设置线程名称jt1.setName("伊卡尔迪1");jt2.setName("佩里西奇2");jt3.setName("坎德雷瓦3");// 启动线程jt1.start();// 设置线程等待该线程终止该方法必须要启动线程try {jt1.join();} catch (InterruptedException e) {e.printStackTrace();}//等待线程jt1终止才会执行线程jt2和jt3jt2.start();jt3.start();}}// 自定义的线程类class JoinThread extends Thread {@Overridepublic void run() {for (int x = 0; x < 5; x++) {System.out.println(Thread.currentThread().getName() + ":" + x);}}}








例4:yield() 暂停当前正在执行的线程对象,并执行其他线程

public class YieldDemo {public static void main(String[] args) {// 创建线程类对象YieldThread yt1 = new YieldThread();YieldThread yt2 = new YieldThread();YieldThread yt3 = new YieldThread();// 设置线程名称yt1.setName("线程1");yt2.setName("线程2");yt3.setName("线程3");//设置优先级yt1.setPriority(9);yt2.setPriority(5);yt3.setPriority(1);// 启动线程yt1.start();yt2.start();yt3.start();}}// 自定义线程类class YieldThread extends Thread {@Overridepublic void run() {for (int x = 0; x < 5; x++) {System.out.println(getName() + ":" + x);// 加入yield()方法Thread.yield();}}}




注:该方法不受优先级影响







例5:setDaemon(true)将一个线程设置为守护线程

public class DaemonDemo {public static void main(String[] args) {// 创建线程类对象ThreadDeamon td1 = new ThreadDeamon();ThreadDeamon td2 = new ThreadDeamon();// 设置线程名称td1.setName("什克里尼亚尔");td2.setName("米兰达");// 设置为守护线程setDaemon(true)td1.setDaemon(true);td2.setDaemon(true);// 启动线程td1.start();td2.start();// 设置主线程Thread.currentThread().setName("国际米兰");for (int x = 0; x < 3; x++) {System.out.println(Thread.currentThread().getName() + ":" + x); }}}// 自定义线程类class ThreadDeamon extends Thread {@Overridepublic void run() {for (int x = 0; x < 20; x++) {System.out.println(getName() + ":" + x);}}}




注:待主线程结束之后,守护线程过会儿才会消亡







例6:sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)

import java.util.Date;public class SleepDemo {public static void main(String[] args) {// 创建线程类对象ThreadSleep ts1 = new ThreadSleep();ThreadSleep ts2 = new ThreadSleep();ThreadSleep ts3 = new ThreadSleep();// 设置线程名称ts1.setName("线程1");ts2.setName("线程2");ts3.setName("线程3");// 启动线程ts1.start();ts2.start();ts3.start();}}class ThreadSleep extends Thread {@Overridepublic void run() {for (int x = 0; x < 10; x++) {System.out.println(getName() + ":" + x + ",日期:" + new Date());// 睡眠1秒中:1000毫秒try {Thread.sleep(1000);// 此方法本身就抛出一个异常!} catch (InterruptedException e) {e.printStackTrace();}}}}






例7:stop()强迫线程停止执行

import java.util.Date;public class StopDemo {public static void main(String[] args) {//创建线程类对象ThreadStop ts = new ThreadStop() ;ts.start() ;//如果3秒中不醒来,终止try {Thread.sleep(3000) ;ts.stop() ;// 表示此方法过时,但还可以使用} catch (InterruptedException e) {e.printStackTrace();}}}// 自定义线程类class ThreadStop extends Thread {@Overridepublic void run() {System.out.println("开始执行了.."+new Date());//子线程进来之后,睡眠5秒中try {Thread.sleep(50000) ;} catch (InterruptedException e) {System.out.println("线程终止了...");}System.out.println("结束执行"+new Date());}}








例8:interrupt()中断线程表示一种状态

import java.util.Date;public class InterruptDemo {public static void main(String[] args) {//创建线程类对象ThreadInterrupt ti = new ThreadInterrupt() ;ti.start() ;//如果3秒中不醒来,中断try {Thread.sleep(3000) ;ti.interrupt() ;//中断一种状态} catch (InterruptedException e) {e.printStackTrace();}}}class ThreadInterrupt extends Thread {@Overridepublic void run() {System.out.println("开始执行..."+new Date());//子线程进来之后,睡眠8秒中try {Thread.sleep(8000) ;} catch (InterruptedException e) {System.out.println("线程终止了...");}System.out.println("结束执行..."+new Date());}}









二、多线程的第二种实现方式


例:

public class MyThreadDemo {public static void main(String[] args) {// 1)创建MyRunnable实例对象MyRunnable my = new MyRunnable();// 2)创建线程类对象// 使用Thread类中的构造方法:public Thread(Runnable target,String name)Thread t1 = new Thread(my, "线程1");Thread t2 = new Thread(my, "线程2");// 启动线程t1.start();t2.start();}}// 自定义线程类实现Runnable接口class MyRunnable implements Runnable {@Overridepublic void run() {for (int x = 0; x < 5; x++) {System.out.println(Thread.currentThread().getName() + ":" + x);}}}









原创粉丝点击