多线程:
基本的概念:
程序:
是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。
进程:
是程序的一次执行过程,或是正在执行的一个程序。是一个动态的过程:有它自身的产生、存在和消亡的过程。——生命周期
>程序是静态的,进程是动态的。
>进程作为资源分配的单位,系统在运行时会为每一个进程分配不同的区域
线程:
进程可进一步细化为线程,是一个程序内部的一条执行路径。
>若一个进程同一时间并行执行多个线程,就是支持多线程的
>线程作为调度和执行的单位,每一个线程拥有独立的运行栈和程序计数器,线程切换的开销小
>一个进程中的多个线程共享相同的内存单元/内存dizhikjian—>他们从同一个堆中分配对象,可以访问相同的变量和对象。这就使得线程间的通讯更简便、高效。但多个线程操作共享的系统资源可能就会带来安全的隐患
使用多线程的优点:
1、提高应用程序的相应。对图形化界面更有意义,可增强用户体验。
2、提高计算机系统CPU的利用率。
3、改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改。
何时需要多线程:
>程序需要同时执行两个或多个任务;
>程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
>需要一些后台运行的程序时。
线程的创建和使用( java.lang.Thread 类):
多线程的创建:
方式一:继承于Thread类
1、创建一个继承于Thread类的子类
2、重写Thread类的run() ——> 将此线程执行的操作声明在run()中
3、创建Thread类的子类对象
4、通过次对象调用start() (1)启动当前线程;(2)调用当前线程的run()。
另一种书写方式:(创建匿名子类)
尝试:
代码
//1、创建一个继承于Thread类的子类 class MyThread extends Thread { //2、重写Thread类的run() @Override public void run() { for(int i = 0 ; i < 10 ; i ++) { if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() + ":" + i); } } } } public class ThreadTest { public static void main(String[] args){ //3、创建Thread类的子类的对象 MyThread myThread = new MyThread(); //4、通过次对象调用start() myThread.start(); //问题一:我们不能通过直接调用run()的方式启动线程 //myThread.run(); //问题二:不可以让已经start()的线程在执行 --- 需要重新创建对象 //myThread.start(); //如下操作仍然是在main线程中执行的。 for(int i = 0 ; i < 10 ; i ++) { if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() + ":" + i); } } } }
结果
调用start()调用当前线程
我们不能通过直接调用run()的方式启动线程
调用run()时并没有调用线程
问题一: 我们不能通过直接调用run()的方式启动线程
问题二:不可以让已经start()的线程再执行 --- 需要重新创建对象
Thread类的有关方法:
1、start();启动当前线程;调用当前线程的run();
2、run();通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
3、currentThread();静态方法,返回执行的当前代码的线程
4、getName();获取当前线程的名字
5、setName();设置当前线程的名字
6、yield();释放当前位置cpu的执行权
7、join();在线程a中调用线程b的join(),此时线程a就进入堵塞状态,直到线程b完全执行完以后,线程a才结束阻塞状态
8、sleep(long milltime);让当前线程“睡眠”指定的milltime毫秒,在指定时间内,当前线程是堵塞状态
9、isAlive();判断当前线程是否存活
每日练习: