一. 进程与线程:
1. 进程:
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
2. 线程:
线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。
3. 执行方式:
① 顺序执行:即程序从上往下一步一步的执行
② 并发执行:指两个或多个事件在同一个时间段内执行
③ 并行执行:指两个或多个事件在同一时刻同时执行
二. 创建多线程的三种方式:
1. 继承Thread类:
继承Thread类后要重写Thread类的run()方法,然后调用start()方法开启线程
public class TestThread1 extends Thread{
public static void main(String[] args){
EatThread eatThread= new EatThread();
DrinkThread drinkThread= new DrinkThread();
eatThread.start();
drinkThread.start();}}
class EatThread extends Thread{
@Override
public void run(){
System.out.println("开始吃饭?...\t" + new Date());
try{
Thread.sleep(5000);} catch(InterruptedException e){
e.printStackTrace();}
System.out.println("结束吃饭?...\t" + new Date());}}
class DrinkThread extends Thread{
@Override
public void run(){
System.out.println("开始喝酒?...\t" + new Date());
try{
Thread.sleep(5000);} catch(InterruptedException e){
e.printStackTrace();}
System.out.println("结束喝酒?...\t" + new Date());}}
此时的运行结果为:
当把主函数(即主线程)改为run()方法开启线程:
public class TestThread1 extends Thread{
public static void main(String[] args){
EatThread eatThread= new EatThread();
DrinkThread drinkThread= new DrinkThread();
eatThread.run();
drinkThread.run();}}
此时的运行结果为:
造成区别的原因时:当使用start()方法开启线程时,各线程是并发执行的,当使用run()方法开启线程时,各线程是顺序执行的。
2. 实现Runnable接口:
与继承Thread类方法类似,实现Runnable接口后要重写run()方法,然后使用Thread类来包装调用start()方法开启线程
public class TestThread2 implements Runnable{
@Override
public void run(){
System.out.println("开始吃饭?...\t" + new Date());
try{
Thread.sleep(5000);} catch(InterruptedException e){
e.printStackTrace();}
System.out.println("结束吃饭?...\t" + new Date());}
public static void main(String[] args){
TestThread2 t1= new TestThread2();
new Thread(t1).start();
Thread thread= new Thread(t1); //对同一对象进行多线程从操作
thread.start();}}
运行结果为:
注意:newThread(t1).start();和Threadthread=newThread(t1);thread.start();这两种写法效果是一样的第一种方法继承Thread类,Thread类也实现了Runnable接口第二种方法实现Runnable接口,类似创建一个代理工具类推荐使用实现Runnable接口的方法实现多线程,可以避免Java单线程的限制线程开启不一定立即执行,由CPU调度执行
3. 实现Callable接口:
① 实现Callable接口,需要返回值类型
② 重写call()方法,需要抛出异常
③ 创建目标对象 : TestThread3 testThread3 = new TestThread3()
④ 创建执行服务 : ExecutorService ser = Executors.newFixedThreadPool(2)
⑤ 提交执行 : Future r1 = ser.submit(testThread3)
⑥ 获取结果 : boolean rst1 = r1.get();
⑦ 关闭服务 : ser.shutdownNow();
public class TestThread3 implements Callable<Boolean>{ //①实现Callable接口,需要返回值类型
private String name;
public TestThread3(String name){
this.name= name;}
@Override
public Boolean call() throws Exception{ //②重写call()方法,需要抛出异常
if(name.equals("张三")){
System.out.println("欢迎"+name);returntrue;}returnfalse;}
public static void main(String[] args) throws ExecutionException, InterruptedException{
//③创建目标对象
TestThread3 t1= new TestThread3("张三");
TestThread3 t2= new TestThread3("李四");
//④创建执行服务
ExecutorService ser= Executors.newFixedThreadPool(2);
//⑤提交执行
Future<Boolean> r1= ser.submit(t1);
Future<Boolean> r2= ser.submit(t2);
//⑥获取结果
boolean rst1= r1.get();
boolean rst2= r2.get();
System.out.println(rst1);
System.out.println(rst2);
//⑦关闭服务
ser.shutdownNow();}}
运行结果:
三. 多线程实例——龟兔赛跑
public class Race implements Runnable{
private static String winner;
@Override
public void run(){for(int i= 1; i<= 100; i++){
// 模拟兔子休息
if(Thread.currentThread().getName().equals("兔子")&& i%10==0){
try{
Thread.sleep(100);} catch(InterruptedException e){
e.printStackTrace();}}
boolean flag= isGameOver(i);
// 如果比赛结束,终止程序if(flag){break;}
// Thread.currentThread()获取当前线程
// Thread.currentThread().getName()获取当前线程名字
System.out.print(Thread.currentThread().getName()+"-->跑了"+i+"步"+"\t");
if(i%5==0)
System.out.println();}}
// 判断是否有胜利者
public boolean isGameOver(int step){if(winner!=null){returntrue;}else{if(step>=100){
winner= Thread.currentThread().getName();
System.out.println("winner is "+winner);returntrue;}}returnfalse;}
public static void main(String[] args){
Race race= new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();}}
结果:
参考:https://blog.csdn.net/vbirdbest/article/details/81282163.