并行与并发
并行
在同一时刻,有多个指令在多个CPU上同时执行
并发
在同一时刻,有多个指令在单个CPU上交替执行
线程与进程
操作系统
操作系统是多进程容器
进程
进程是多线程的容器
线程是进程中的单个顺序控制流,是一条执行路径
单线程程序
一个进程如果只有一条执行路径,则称为单线程程序
多线程程序
一个进程如果有多条执行路径,则称为多线程程序
多线程的创建方式
方式一:继承Thread类
Java是通过java.lang.Thread类代表线程
按照面向对象的思想,Thread类提供了实现多线程的方式,所有的线程对象都必须是Thread类或其子类的实例(Java是并发执行)每个线程的作用是执行一段程序流,即一段顺序执行的代码
实现原理:
因为Thread对象(target=null)的start();调用start0();再调用Thread的run();,内部为null不执行
方式:
1.定义一个子类MyThread继承(extends)Thread类
2.重写run()方法
3.创建MyTread类的对象
4.对象.start();,启动线程
例:
public class MyThread extends Thread { @Override public void run() { System.out.println("子线程创建完毕"); } }
public class Test { public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.run(); } }
优点:
编码简单
缺点:
扩展性差,Java只能继承一个父类
1.为什么不直接调用了run方法,而是调用start启动线程?
直接调用run方法会当成普通方法执行,此时相当于还是单线程执行
只有调用start方法才是启动一个新的线程执行2.把主线程任务放在子线程之前了。
这样主线程一直是先跑完的,相当于是一个单线程的效果总结
1.线程对象调用start方法,start方法通知JVM为当前线程对象开辟新的run方法运行栈空间, 执行当前线程对象的run方法
2.每个线程的run方法执行空间属于线程私有
3.某一个线程运行中出现异常,不会影响其它线程的执行(不考虑同步: 锁的问题)
方式二: 实现Runnable接口
方式:
1.定义一个类MyRunnable实现(implements)Runnable接口
2.在MyRunnable类中重写run()方法
3.创建MyRunnable类的对象
4.创建Thread类的对象,把MyRunnable对象作为构造器的形参
5.Thread类的对象.start();,启动线程
实现原理:
target地址值传递
Thread的构造器
优点:
共享一个数据,线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强
缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("子线程创建完毕"); } }
public class Test { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } }
方式二:实现Runnable接口(匿名内部类)
方式:
1.可以创建Runnable的匿名内部类对象
2.交给Tread处理
3.调用线程对象.start();,启动线程
public class Test { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("子线程创建完毕"); } }); } }
1.Thread类实现多线程与实现Runnable实现多线程的区别?
如果一个类继承Thread,则不适合资源共享,但是如果实现了Runable接口的话,则很容易的实现资源共享
2.实现Runnable接口比继承Thread类所具有的优势:
适合多个相同的程序代码的线程去共享同一个资源
可以避免java中的单继承的局限性
增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立
public class Demo { public static void main(String[] args) { //1 Runnable task = new Runnable() { @Override public void run() { System.out.println("线程A执行!!!"); } };