admin管理员组文章数量:1026989
线程的介绍
线程与进程
进程:
1.指在运行中的程序,例如使用微信就启动一个进程,操作系统就会为 该进程分配内存空间;
2.进程是程序的一次执行的过程,或者是正在运行的一个程序;是动态过程,有它自身的产生、存在和消亡的过程。
线程:
1.线程由进程创建的,是进程的一个实体;
2.一个进程可以拥有多个线程;
3.单线程:同一时刻,只允许执行一个线程;
4.多线程:同一时刻,可以执行多个线程。
并发和并行
并发:
同一时刻,多个任务交替执行;单核CPU实现的多任务就是并发
并行:
同一个时刻,多个任务同时执行,多核CPU可以实现并行
线程的使用
继承Thread创建线程,重写run方法
public static void main(String[] args) throws InterruptedException { //创建Dog对象,可以当做线程使用Dog dog = new Dog();//启动线程,执行dog的run方法dog.start(); //当main线程启动一个子线程 Thread -0,主线程不会阻塞,而是继续执行//主线程和子线程交替执行 for (int i = 0; i < 80; i++) {System.out.println("主线程 i = " + i + Thread.currentThread().getName());Thread.sleep(1000);} }
//演示通过继承Thread来创建线程 /*说明: * 1.当一个类继承Thread类,该类就可以做为线程使用 * 2.需要重写run方法,在run方法里面写自己需要实现的结果 * 3.Thread类中的run方法,是Thread类实现了Runnable接口的run方法 * */ class Dog extends Thread{ @Overridepublic void run() {//重写run方法,设置自己需要的实现的结果 int temp = 0;while (true) {temp ++;//该线程在1s钟,在控制台输出:汪汪汪...System.out.println("汪汪汪..." + "循环次数:" + temp + Thread.currentThread().getName());//让线程休息1stry {Thread.sleep(1000);//1000 = 1s} catch (InterruptedException e) {e.printStackTrace();} //当循环20次后退出循环if(temp == 100){break;}} } }
实现Runnable接口,重写run方法
说明:
1.JAVA是单继承的,在某些情况下一个类可能已经继承了某个父类,这是就不能再去继承Thread类方法来创建线程。
2.因此在上面那种情况下,就只能使用提供的另一个方法创建线程,通过实现Runnable接口创建线程。
public static void main(String[] args) { Tiger tiger = new Tiger(); //调用Thread类来调用start方法去实现Thread thread = new Thread(tiger);thread.start(); }
class Tiger implements Runnable{ int count = 0; @Overridepublic void run() {//普通方法while (true){count ++;System.out.println("小老虎..." + count + Thread.currentThread().getName() ); try {Thread.sleep(1000);//延时1s} catch (InterruptedException e) {e.printStackTrace();} if(count == 20){break;}} } }
使用jconsole监控进程执行情况
多个子线程案例
public static void main(String[] args) { //在main线程中启动两个子线程Banana banana = new Banana();Thread thread = new Thread(banana);thread.start(); Apple apple = new Apple();Thread thread1 = new Thread(apple);thread1.start(); }
//每隔1s输出,且输出100次 class Banana implements Runnable{ @Overridepublic void run() { int num01 = 0;while (true){num01 ++;System.out.println("Hello World" + num01 + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} if (num01 == 10){break;} } } } // class Apple implements Runnable{ @Overridepublic void run() {int num02 = 0;while (true){num02++; System.out.println("hi ..." + num02 + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} if (num02 == 5){break;} } } }
继承Thread和实现Runnable接口的区别
-
通过继承Thread或者实现Runnable接口来创建线程本质是没有区别的;Thread类的本身就实现了Runnable接口
-
实现Runnable接口方式更加适合多个线程共享一个资源的情况,并且避免了单继承的限制,建议一般情况下使用Runnable接口
练习题:实现多线程售票问题
public static void main(String[] args) { //使用多线程,模拟三个窗口同时售票/* //第一种方法:使用Thread类SellTicket01 sellTicket01 = new SellTicket01();SellTicket01 sellTicket02 = new SellTicket01();SellTicket01 sellTicket03 = new SellTicket01(); sellTicket01.start();sellTicket02.start();sellTicket03.start();*/ //第二种方法:实现Runnable接口SellTicket02 sellTicket02 = new SellTicket02(); Thread thread01 = new Thread(sellTicket02);Thread thread02 = new Thread(sellTicket02);Thread thread03 = new Thread(sellTicket02); thread01.start();thread02.start();thread03.start(); }
//第一种方法:继承Thread class SellTicket01 extends Thread{ //总票数100张private static int num = 100; @Overridepublic void run() { while (true){if (num <= 0){System.out.println("票已售完...");break;} --num;System.out.println("售票处:" + Thread.currentThread().getName() + "\t" + "售出一张票" + "\t" + "剩余票数=" + num);//延时1stry {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}} }
//第二种方法:实现Runnable接口 //第一种方法:继承Thread class SellTicket02 implements Runnable{//总票数100张private int num = 100;@Overridepublic void run() {while (true){if (num <= 0){System.out.println("票已售完...");break;}--num;System.out.println("售票处:" + Thread.currentThread().getName() + "\t" +"售出一张票" + "\t" + "剩余票数=" + num);//延时1stry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}} }
通知程序退出(程序终止)
1.当线程完成任务后,会自动退出
2.可以通过使用变量来控制run方法退出的方式停止线程,即通知方式
public static void main(String[] args) throws InterruptedException {Peach peach = new Peach();peach.start();//先延时10s,将线程停止退出Thread.sleep(10*1000);//停止线程peach.setLoop(false);}
class Peach extends Thread{private int num = 0;private boolean loop = true;//可修改looppublic void setLoop(boolean loop) {this.loop = loop;}@Overridepublic void run() {while (loop){num ++;System.out.println("Peach线程正在执行..." + "\t"+Thread.currentThread().getName() + "\t" +num);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}} }
线程中断
1.setName //设置线程名称,使与参数name相同
2.getName //返回该线程的名称
3.start //使该线程开始执行
4.run //调用线程对象run方法
5.setPriority //更改线程的优先级
6.getPriority //获取线程的优先级
7.sleep //在指定的毫秒数内让当前正在执行的线程休眠(暂时执行)
8.interrupt //中断线程
注意:
1.start底层会创建新的线程,调用run,run就是一个方法的调用,不会启动新的线程
2.线程优先级的范围:MAX_PRIORITY = 10 ;MIN_PRIORITY = 1;NORM_PRIORITY = 5
3.interrupt,中断程序;并未使得程序结束只是暂停;一般用于中断正在休眠的线程
4.sleep;线程的静态方法。使得当前线程休眠
public static void main(String[] args) throws InterruptedException {Lemon lemon = new Lemon();lemon.setName("线程01");//修改线程名称lemon.setPriority(Thread.MIN_PRIORITY);//设置优先级:最低lemon.start();System.out.println(lemon.getName());for(int j = 0 ;j < 5;j++){Thread.sleep(1000);System.out.println("hello..." + j);}lemon.interrupt();//执行到中断方法,就会中断lemon线程的休眠}
class Lemon extends Thread{@Overridepublic void run() {while (true) {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + "吃柠檬..." + i);}System.out.println(Thread.currentThread().getName() + "吃柠檬..." + "休眠中...");try {Thread.sleep(50 * 1000);} catch (InterruptedException e) {System.out.println(Thread.currentThread().getName() + "吃柠檬..." + "被interrupt ...");}}} }
线程插队
1.yield:线程的礼让
让出CPU,让其他线程执行,但礼让的时间不确定,所以也不一定成功
2.join:线程插入
插队的线程一旦插队成功,则肯定先执行完插入的线程所有的任务
public static void main(String[] args) throws InterruptedException {Mango mango = new Mango();mango.start();for (int i = 0; i < 10; i++) {Thread.sleep(1000);System.out.println(Thread.currentThread().getName()+ "\t" + "吃猕猴桃..." +"\t" + i);if (i == 5){System.out.println("主线程让子线程先执行完...");mango.join();//插队处理:让子线程提前执行//Thread.yield();//让子线程提前执行,但不一定成功}}}
class Mango extends Thread{int num = 0;@Overridepublic void run() {while (true) {for (int i = 0; i < 10; i++) {num ++;try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "\t" + "吃芒果..." + "\t" + i);}if (num == 20){break;}}} }
线程插队练习:
1.主线程每隔1s,输出hi,一共10次 2.当输出到hi 5时,启动一个子线程(要求 实现Runnable),每隔1s输出hello,等该线程输出10次hello后,退出 3.主线程继续输出hi,直到主线程退出.
public static void main(String[] args) throws InterruptedException {Almond almond = new Almond();Thread thread = new Thread(almond);for (int i = 0; i < 10; i++) {Thread.sleep(1000);System.out.println("线程:" + Thread.currentThread().getName() + "\t" + "hi..."+"\t" + i);if (i == 5){System.out.println("允许子线程执行...");thread.start();//开启子线程thread.join();//将所有空间给子线程执行}}}
//定义一个类并实现Runnable接口 class Almond implements Runnable{int num = 0;@Overridepublic void run() {while (true){num++;try {Thread.sleep(1000);System.out.println("线程:" + Thread.currentThread().getName()+"\t" + "hello..." + "\t" + num);} catch (InterruptedException e) {e.printStackTrace();}if (num == 10){break;}}} }
守护线程
用户线程和守护线程
1.用户线程:就是工作线程,当线程的任务执行完或通知方式结束
2.守护线程:一般是为工作线程服务的,当所有的用户线程结束,守护线程自动结束
3.常见的守护线程:垃圾回收机制
public static void main(String[] args) throws InterruptedException {Grape grape = new Grape();//1.如果希望当main线程结束后,子线程自动结束//2.只需要将子线程设为守护线程grape.setDaemon(true);//将子线程设为守护线程grape.start();for (int i = 0; i < 10; i++) {//主线程System.out.println("线程:" + Thread.currentThread().getName() + "\t" + "吃猕猴桃" +"\t" + i);Thread.sleep(1000);}}
class Grape extends Thread{int num = 0;@Overridepublic void run() {while (true) {num ++;try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "\t" + "吃葡萄..."+ "\t" + num);}} }
线程的介绍
线程与进程
进程:
1.指在运行中的程序,例如使用微信就启动一个进程,操作系统就会为 该进程分配内存空间;
2.进程是程序的一次执行的过程,或者是正在运行的一个程序;是动态过程,有它自身的产生、存在和消亡的过程。
线程:
1.线程由进程创建的,是进程的一个实体;
2.一个进程可以拥有多个线程;
3.单线程:同一时刻,只允许执行一个线程;
4.多线程:同一时刻,可以执行多个线程。
并发和并行
并发:
同一时刻,多个任务交替执行;单核CPU实现的多任务就是并发
并行:
同一个时刻,多个任务同时执行,多核CPU可以实现并行
线程的使用
继承Thread创建线程,重写run方法
public static void main(String[] args) throws InterruptedException { //创建Dog对象,可以当做线程使用Dog dog = new Dog();//启动线程,执行dog的run方法dog.start(); //当main线程启动一个子线程 Thread -0,主线程不会阻塞,而是继续执行//主线程和子线程交替执行 for (int i = 0; i < 80; i++) {System.out.println("主线程 i = " + i + Thread.currentThread().getName());Thread.sleep(1000);} }
//演示通过继承Thread来创建线程 /*说明: * 1.当一个类继承Thread类,该类就可以做为线程使用 * 2.需要重写run方法,在run方法里面写自己需要实现的结果 * 3.Thread类中的run方法,是Thread类实现了Runnable接口的run方法 * */ class Dog extends Thread{ @Overridepublic void run() {//重写run方法,设置自己需要的实现的结果 int temp = 0;while (true) {temp ++;//该线程在1s钟,在控制台输出:汪汪汪...System.out.println("汪汪汪..." + "循环次数:" + temp + Thread.currentThread().getName());//让线程休息1stry {Thread.sleep(1000);//1000 = 1s} catch (InterruptedException e) {e.printStackTrace();} //当循环20次后退出循环if(temp == 100){break;}} } }
实现Runnable接口,重写run方法
说明:
1.JAVA是单继承的,在某些情况下一个类可能已经继承了某个父类,这是就不能再去继承Thread类方法来创建线程。
2.因此在上面那种情况下,就只能使用提供的另一个方法创建线程,通过实现Runnable接口创建线程。
public static void main(String[] args) { Tiger tiger = new Tiger(); //调用Thread类来调用start方法去实现Thread thread = new Thread(tiger);thread.start(); }
class Tiger implements Runnable{ int count = 0; @Overridepublic void run() {//普通方法while (true){count ++;System.out.println("小老虎..." + count + Thread.currentThread().getName() ); try {Thread.sleep(1000);//延时1s} catch (InterruptedException e) {e.printStackTrace();} if(count == 20){break;}} } }
使用jconsole监控进程执行情况
多个子线程案例
public static void main(String[] args) { //在main线程中启动两个子线程Banana banana = new Banana();Thread thread = new Thread(banana);thread.start(); Apple apple = new Apple();Thread thread1 = new Thread(apple);thread1.start(); }
//每隔1s输出,且输出100次 class Banana implements Runnable{ @Overridepublic void run() { int num01 = 0;while (true){num01 ++;System.out.println("Hello World" + num01 + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} if (num01 == 10){break;} } } } // class Apple implements Runnable{ @Overridepublic void run() {int num02 = 0;while (true){num02++; System.out.println("hi ..." + num02 + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} if (num02 == 5){break;} } } }
继承Thread和实现Runnable接口的区别
-
通过继承Thread或者实现Runnable接口来创建线程本质是没有区别的;Thread类的本身就实现了Runnable接口
-
实现Runnable接口方式更加适合多个线程共享一个资源的情况,并且避免了单继承的限制,建议一般情况下使用Runnable接口
练习题:实现多线程售票问题
public static void main(String[] args) { //使用多线程,模拟三个窗口同时售票/* //第一种方法:使用Thread类SellTicket01 sellTicket01 = new SellTicket01();SellTicket01 sellTicket02 = new SellTicket01();SellTicket01 sellTicket03 = new SellTicket01(); sellTicket01.start();sellTicket02.start();sellTicket03.start();*/ //第二种方法:实现Runnable接口SellTicket02 sellTicket02 = new SellTicket02(); Thread thread01 = new Thread(sellTicket02);Thread thread02 = new Thread(sellTicket02);Thread thread03 = new Thread(sellTicket02); thread01.start();thread02.start();thread03.start(); }
//第一种方法:继承Thread class SellTicket01 extends Thread{ //总票数100张private static int num = 100; @Overridepublic void run() { while (true){if (num <= 0){System.out.println("票已售完...");break;} --num;System.out.println("售票处:" + Thread.currentThread().getName() + "\t" + "售出一张票" + "\t" + "剩余票数=" + num);//延时1stry {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}} }
//第二种方法:实现Runnable接口 //第一种方法:继承Thread class SellTicket02 implements Runnable{//总票数100张private int num = 100;@Overridepublic void run() {while (true){if (num <= 0){System.out.println("票已售完...");break;}--num;System.out.println("售票处:" + Thread.currentThread().getName() + "\t" +"售出一张票" + "\t" + "剩余票数=" + num);//延时1stry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}} }
通知程序退出(程序终止)
1.当线程完成任务后,会自动退出
2.可以通过使用变量来控制run方法退出的方式停止线程,即通知方式
public static void main(String[] args) throws InterruptedException {Peach peach = new Peach();peach.start();//先延时10s,将线程停止退出Thread.sleep(10*1000);//停止线程peach.setLoop(false);}
class Peach extends Thread{private int num = 0;private boolean loop = true;//可修改looppublic void setLoop(boolean loop) {this.loop = loop;}@Overridepublic void run() {while (loop){num ++;System.out.println("Peach线程正在执行..." + "\t"+Thread.currentThread().getName() + "\t" +num);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}} }
线程中断
1.setName //设置线程名称,使与参数name相同
2.getName //返回该线程的名称
3.start //使该线程开始执行
4.run //调用线程对象run方法
5.setPriority //更改线程的优先级
6.getPriority //获取线程的优先级
7.sleep //在指定的毫秒数内让当前正在执行的线程休眠(暂时执行)
8.interrupt //中断线程
注意:
1.start底层会创建新的线程,调用run,run就是一个方法的调用,不会启动新的线程
2.线程优先级的范围:MAX_PRIORITY = 10 ;MIN_PRIORITY = 1;NORM_PRIORITY = 5
3.interrupt,中断程序;并未使得程序结束只是暂停;一般用于中断正在休眠的线程
4.sleep;线程的静态方法。使得当前线程休眠
public static void main(String[] args) throws InterruptedException {Lemon lemon = new Lemon();lemon.setName("线程01");//修改线程名称lemon.setPriority(Thread.MIN_PRIORITY);//设置优先级:最低lemon.start();System.out.println(lemon.getName());for(int j = 0 ;j < 5;j++){Thread.sleep(1000);System.out.println("hello..." + j);}lemon.interrupt();//执行到中断方法,就会中断lemon线程的休眠}
class Lemon extends Thread{@Overridepublic void run() {while (true) {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + "吃柠檬..." + i);}System.out.println(Thread.currentThread().getName() + "吃柠檬..." + "休眠中...");try {Thread.sleep(50 * 1000);} catch (InterruptedException e) {System.out.println(Thread.currentThread().getName() + "吃柠檬..." + "被interrupt ...");}}} }
线程插队
1.yield:线程的礼让
让出CPU,让其他线程执行,但礼让的时间不确定,所以也不一定成功
2.join:线程插入
插队的线程一旦插队成功,则肯定先执行完插入的线程所有的任务
public static void main(String[] args) throws InterruptedException {Mango mango = new Mango();mango.start();for (int i = 0; i < 10; i++) {Thread.sleep(1000);System.out.println(Thread.currentThread().getName()+ "\t" + "吃猕猴桃..." +"\t" + i);if (i == 5){System.out.println("主线程让子线程先执行完...");mango.join();//插队处理:让子线程提前执行//Thread.yield();//让子线程提前执行,但不一定成功}}}
class Mango extends Thread{int num = 0;@Overridepublic void run() {while (true) {for (int i = 0; i < 10; i++) {num ++;try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "\t" + "吃芒果..." + "\t" + i);}if (num == 20){break;}}} }
线程插队练习:
1.主线程每隔1s,输出hi,一共10次 2.当输出到hi 5时,启动一个子线程(要求 实现Runnable),每隔1s输出hello,等该线程输出10次hello后,退出 3.主线程继续输出hi,直到主线程退出.
public static void main(String[] args) throws InterruptedException {Almond almond = new Almond();Thread thread = new Thread(almond);for (int i = 0; i < 10; i++) {Thread.sleep(1000);System.out.println("线程:" + Thread.currentThread().getName() + "\t" + "hi..."+"\t" + i);if (i == 5){System.out.println("允许子线程执行...");thread.start();//开启子线程thread.join();//将所有空间给子线程执行}}}
//定义一个类并实现Runnable接口 class Almond implements Runnable{int num = 0;@Overridepublic void run() {while (true){num++;try {Thread.sleep(1000);System.out.println("线程:" + Thread.currentThread().getName()+"\t" + "hello..." + "\t" + num);} catch (InterruptedException e) {e.printStackTrace();}if (num == 10){break;}}} }
守护线程
用户线程和守护线程
1.用户线程:就是工作线程,当线程的任务执行完或通知方式结束
2.守护线程:一般是为工作线程服务的,当所有的用户线程结束,守护线程自动结束
3.常见的守护线程:垃圾回收机制
public static void main(String[] args) throws InterruptedException {Grape grape = new Grape();//1.如果希望当main线程结束后,子线程自动结束//2.只需要将子线程设为守护线程grape.setDaemon(true);//将子线程设为守护线程grape.start();for (int i = 0; i < 10; i++) {//主线程System.out.println("线程:" + Thread.currentThread().getName() + "\t" + "吃猕猴桃" +"\t" + i);Thread.sleep(1000);}}
class Grape extends Thread{int num = 0;@Overridepublic void run() {while (true) {num ++;try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "\t" + "吃葡萄..."+ "\t" + num);}} }
本文标签: 线程的介绍
版权声明:本文标题:线程的介绍 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/IT/1694660500a254663.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论