5.1 如何创建和了解多线程
一个进程中又可以包含一个或多个线程,一个线程就是一个程序内部的一条执行线索在单线程中,程序代码按调用顺序依次往下执行,在这种情况下,当主函数调用了子函数主函数必须等待子函数返回后才能继续往下执行,不能实现两段程序代码同时交替运行的效果。如果要一程序中实现多段代码同时交替运行,就需产生多个线程,并指定每个线程上所要运行的程序代码段,这就是多线程
当程序启动运行时,就自动产生了一个线程,主函数 ain 就是在这个线程上运行的,当不再产生新的线程时,程序就是单线程的,比如以前的例子,它们都是单线程的。
创建多线程有两种方法:继承 Thread 类和实现 Runnable 接口
public class ThreadDemo1{public static void main(String args[]){new TestThread().start();//run();while(true){System.out.println("main thread is running");}}
}
class TestThread extends Thread{public void run(){while(true){System.out.println(Thread.currentThread().getName()+"is running");}}
}
可见,在单线程中,main函数必须等到TestThread.run函数返回后才能继续往下执行。而在多线程中,main 函数调用 TestThread.start0方法启动了 TestThreadrun0函数后,main函数不等待 TestThreadrun 函数返回就继续运行,TestThreadrun 函数在一边独自运行,不影响原来的 main 函数的运行,这好比将一个1G的CPU分成了两个500M的CPU在一个CPU上运行main函数,而TestThread.run 则在另一个CPU上运行,但它们都在向同-个显示器上输出,所以我们看到两个 while 循环处的代码同时交替运行
(1)要将一段代码在一个新的线程上运行,该代码应该在一个类的 iun 函数中,并且run函数所在的类是Thread类的子类。倒过来看,要实现多线程,必须编写一个继承了Thread类的子类,子类要覆盖Thread 类中的 run 函数,在子类的 run 函数中调用想在新线程上运行的程序代码。
(2)启动一个新的线程,不是直接调用 Thread 子类对象的run 方法,而是调用Thread子类对象的 start(从Thread 类中继承的)方法,Thread 类对象的 start 方法将产生一个新的线程,并在该线程上运行该 Thread 类对象中的 run 方法,根据面向对象的多态性,在该线程上实际运行的是Thread 子类(也就是我们编写的那个类)对象中的 run 方法
(3)由于线程的代码段在 run 方法中,那么该方法执行完以后,线程也就相应的结束了,因而可以通过控制 run 方法中的循环条件来控制线程的终止
public class ThreadDemo3{public static void main(String args[]){//w Thread().start();//run();TestThread tt = new TestThread();Thread t = new Thread(tt);t.start();while(true){System.out.println("main thread is running");}}
}class TestThread implements Runnable{public void run(){while(true){System.out.println(Thread.currentThread().getName()+"is running");}}
}
public class ThreadDemo4{public static void main(String [] args){//w Thread().start();//run();TestThread t = new TestThread();t.start();t.start();t.start();t.start();}
}class TestThread extends Thread{private int tickets = 100;public void run(){while(true){if(tickets > 0)System.out.println(Thread.currentThread().getName()+"is saling ticket" + tickets--);}}
}
public class ThreadDemo4{public static void main(String [] args){//w Thread().start();//run();new ThreadTest().start();new ThreadTest().start();new ThreadTest().start();new ThreadTest().start();}
}class ThreadTest extends Thread{private int tickets = 100;public void run(){while(true){if(tickets > 0)System.out.println(Thread.currentThread().getName()+"is saling ticket" + tickets--);}}
}
public class ThreadDemo5{public static void main(String [] args){ThreadTest t = new ThreadTest();new Thread(t).start();new Thread(t).start();new Thread(t).start();new Thread(t).start();}
}class ThreadTest implements Runnable{private int tickets = 100;public void run(){while(true){if(tickets > 0)System.out.println(Thread.currentThread().getName()+"is saling ticket" + tickets--);}}
}
可见,实现 Runnable 接口相对于继承Thread 类来说,有如下显著的好处:
(1)适合多个相同程序代码的线程去处理同一资源的情况,把虚拟 CPU(线程)同程序的代码、数据有效分离,较好地体现了面向对象的设计思想
(2) 可以避免由于 Java 的单继承特性带来的局限。我们经常碰到这样一种情况,即当我们要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现 Runnable 接口的方式了
(3)有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程可以操作相同的数据,与它们的代码无关。当共享访问相同的对象时,即它们共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了 Runnable 接口的类的实例。
public class DaemonThread{public static void main(String[] args){ThreadTest t = new ThreadTest();Thread tt = new Thread(t);tt.setDaemon(true);tt.start();}
}
class ThreadTest implements Runnable{public void run(){while(true){System.out.println(Thread.currentThread().getName()+" is running." );}}
}
public class JoinThread{public static void main(String[] args){ThreadTest t = new ThreadTest();Thread pp = new Thread(t);pp.start();int i = 0;while(true){if(i == 100){try{pp.join();}catch(Exception e){System.out.println(e.getMessage());}}System.out.println("main Thread"+ i++);}}
}
class ThreadTest implements Runnable{public void run(){String str = new String();int i = 0;while(true){System.out.println(Thread.currentThread().getName()+" " + i++ );}}
}
1.当我们编写一个网络聊天程序时,如果使用的是单线程编程模式,通常的程序流程
(1)如果一方从键盘上读取了数据并发送给了对方,程序运行到“读取对方回送的数据”并一直等待对方回送数据,如果对方没有回应,程序不能再做其他任何事情,这时程序处于阳寨状态,即使用户想正常终止程序运行都不可能,更不能实现“再给对方发送一条信息,催促对方赶快应答”这样的事情了
(2)如果程序没有事先从键盘上读取数据并向外发送,程序将一直在“从键盘上读取程序无法到达“读取对方回送的数据”处数据”处阻塞,即使有数据从网上发送过来,程序将不能收到别处先主动发送过来的数据。
使用多线程模式编写这个程序后,发送过程与接收过程在两个不同的线程上运行,彼此之间没有任何约束,用户就可以随心所欲地发送和接收数据了。
2.如果程序要将数据库一个表中的所有记录复制到另外一个表中,利用循环将源表中的记录逐一取出并插入到目标表中,当表中的记录有百万条以上,这个复制过程的时间将非常长,当我们想放弃这次复制时,在单线程模式下,我们所能做的只有一直无奈地等到这个费时的操作完成或是做出类似关机一样的野蛮行为了。我们可以用多线程编写这样的应用,由主线程负责表记录的复制,复制代码放在一个循环语句中,循环条件由一个boolean变量来控制
创建一个新的线程,该线程与用户交互,接收用户的键盘输入,当接收到用户的停止命令时,新线程将主线程的循环条件 bFlag 设置为假,即通知主线程在下次检查循环条件时结束复制过程,具体的程序代码见本章最后的一节(如何控制线程的生命)
3,多线程中的另外一个比较典型的例子就是 www 服务器,我们都知道,www 的服务器是可以同时为若干个浏览者服务的,这就需要它为每一个来访者都创建一个线程。如果它是单线程的话,在一个时间段就只能为一个人服务,其他人只有干等的份了
5.1 如何创建和了解多线程相关推荐
- Python 技术篇-多线程的2种创建方法,多线程的简单用法,快速上手
方法一:直接创建 hello 是调用的方法名,hello 如果要传参的话要放到后面的()里,并且后面要有个逗号,没有参数也要加个空的 (). 缺点:不能自由操作线程,不好控制,不会返回对象. impo ...
- java线程的创建线程_多线程(Thread、线程创建、线程池)
第1章 多线程 1.1 多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序, ...
- java线程创建销毁_c++多线程的创建挂起执行与销毁
资源简介 1. 创建一个基于对话框的应用程序.并增加如图所示控件:分别为3个进度条控件关联三个进度条类型的变量:并在对话框的初始化函数中,设定进度条的范围:为编辑框关联一个整型的变量:为12个按钮添加 ...
- springboot创建及使用多线程的几种方式
在数据处理中,多线程用到的场景很多,在满足计算机CPU处理能力的情况下,使用多线程可以明显提高程序运行效率,缩短大数据处理的能力.作为java程序开发,离不开spring,那么在spring中怎么创建 ...
- java 怎么启动多线程_了解Java多线程及如何创建和启动多线程?
1 . 进程与线程 至今为止,我们开发的程序在同一时间只能执行一项任务,如果程序执行中遇到了耗时的任务,程序必须等待该任务完成后才能执行后续的代码.这样的单线程结构不能充分利用计算机的硬件资源,代码运 ...
- java 镶嵌创建线程_Java多线程——之一创建线程的四种方法
1.实现Runnable接口,重载run(),无返回值 package thread; public class ThreadRunnable implements Runnable { public ...
- c#滚动条创建实例,多线程
1.滚动条 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data ...
- java 创建线程_java多线程|创建线程的各种方式
javaDEMO 本网站记录了最全的各种JavaDEMO ,保证下载,复制就是可用的,包括基础的, 集合的, spring的, Mybatis的等等各种,助力你从菜鸟到大牛,记得收藏哦~~https: ...
- Java多线程学习(二)---线程创建方式
线程创建方式 摘要: 1. 通过继承Thread类来创建并启动多线程的方式 2. 通过实现Runnable接口来创建并启动线程的方式 3. 通过实现Callable接口来创建并启动线程的方式 4. 总 ...
最新文章
- PCL:基于PCL绘制包围盒基础介绍(1)
- 操作符*或者-的重载
- POJ 3264 Balanced Lineup 【线段树】
- 零基础想学Python,明白这2点,越快年薪30W!
- python 英文字典-python如何制作英文字典
- 三对角矩阵(特殊矩阵)
- java IO流的概念理解
- idea 类注释模板
- pip使用清华镜像源安装库
- Android-手撸抖音“潜艇大挑战”,非科班面试之旅
- 对接支付宝App支付接口详解
- 图对比学习的应用(NCL,SimGRACE,ClusterSCL)
- kafka comsumer消费消息后不commit offset的情况分析
- hdu 1429	胜利大逃亡(续)
- HIDS-ebpf-0
- 斐波那契数列(python)
- Django-应用app名配置中文显示
- ZZULIOJ-1012,求绝对值(Java)
- ELK系列(四)、Logstash读取nginx日志写入ES中
- 三点法求点三维坐标实验
热门文章
- 转录组分析流程|TransDecoder预测转录本的开放阅读框(二)
- 我自学web前端的心得
- Java之获取时间/日期/时间戳及格式化
- rimraf删除node_modules
- for循环遍历集合取出其中某一项的值
- lj245a引脚功能图_ULN2003A引脚图及功能-uln2003a原理
- 软件测试项目服务,什么是优质的测试服务?
- drawRect消耗大量内存详解
- Swift-类和结构体
- 广西大学计算机研究所宿舍,广西大学宿舍条件如何_几人间?_广西大学怎么样_是985吗?...