赞
踩
进程是系统进行资源分配和调用的独立单元,每一个进程都有它的独立的内存空间和系统资源。
多进程操作系统是指在同一个时段内可以执行多个任务
单进程操作系统是指在同一个时段内只能执行单个任务
a) Windows操作系统-多进程单用户操作系统
b) Dos操作系统-单进程的操作系统
c) Linux操作系统-多用户多进程的操作系统
理论上是可以的,实际上N个项目去运行,多核CPU会分配时间片,时间片到了就退出CPU资源
注意:N个项目去运行,谁先抢到CPU资源,谁就先运算
线程是进程里面的一条执行路径,每个线程同享进程里面的内存空间和系统资源
进程:进程之间的内存空间和系统资源是独立的
线程:同样一个进程里的线程之间是共享内存空间和系统资源的
进程里:可以有一条或一条以上的线程
进程里只有一条线程的情况下,这条线程就叫做主线程
进程里有多条线程的情况下,只有一条线程叫做主线程
Ps:线程是在进程里的,他们是包裹关系
都是
- Thread类
- Runnable接口
- Callable接口
- 线程池(重点:自定义线程池)
Thread类
public class Test01 { public static void main(String[] args) { //创建子线程的对象 MyThread t = new MyThread(); //启动线程 t.start(); } } //自定义线程类 class MyThread extends Thread{ //该线程类的对象抢到CPU资源后,就会执行run() @Override public void run() { for (int i = 1 ; i <= 5; i++) { System.out.println(i); } } }
Runnable接口 - 任务类
public class Test02 { public static void main(String[] args) { //创建子线程,并把任务交给他 Thread t = new Thread(new Task()); //启动线程 t.start(); } } //任务类 class Task implements Runnable{ @Override public void run() { for (int i = 1 ; i <= 5; i++) { System.out.println(i); } } }
主线程打印1-200,子线程打印1-200
public class Test01 { public static void main(String[] args) { MyThread t = new MyThread(); t.start(); for (int i = 1; i <= 200; i++) { System.out.println("主线程:" + i); } } } class MyThread extends Thread{ @Override public void run() { for (int i = 1; i <= 200; i++) { System.out.println("子线程:" + i); } } }
线程类的使用步骤:
继承Thread,重写run方法,创建线程对象,调用start方法(并非马上调用run方法)
任务类的使用步骤:
实现Runnable接口,重写run方法,创建Runnable对象,通过new Thread(task).start()
主线路从上往下,多线程多条执行路线(随机)
经典面试题:请问当我们编写一个单纯的main方法时,此时该程序是否为单线程的?为什么?
是多线程的程序,因为启动主线程,垃圾回收器也会启动,垃圾回收器是一个后台线程
需求:创建3个线程,分别设置不同的优先级别,观察输出结果
注意:优先级别只是概率不同
public class Test01 { public static void main(String[] args) { A a = new A(); B b = new B(); C c = new C(); //设置优先级别 a.setPriority(Thread.MAX_PRIORITY);//10 b.setPriority(Thread.NORM_PRIORITY);//5 c.setPriority(Thread.MIN_PRIORITY);//1 a.start(); b.start(); c.start(); } } class A extends Thread{ @Override public void run() { for(int i = 0;i<= 200;i++){ System.out.println("A:" + i); } } } class B extends Thread{ @Override public void run() { for(int i = 0;i<= 200;i++){ System.out.println("B:" + i); } } } class C extends Thread{ @Override public void run() { for(int i = 0;i<= 200;i++){ System.out.println("C:" + i); } } }
public class Test01 { public static void main(String[] args) { //给线程定义名字 new MyThread("A").start(); new MyThread("B").start(); } } class MyThread extends Thread{ public MyThread(String name) { super(name); } @Override public void run() { for(int i = 0;i<= 200;i++){ //获取当前线程对象 Thread t = Thread.currentThread(); System.out.println(t.getName() + ":" + i); } } }
需求:编写一个抽取学员回答问题的程序,要求倒数三秒后输出被抽中的学员姓名
Thread.sleep(1000); --> Thread类的静态方法,休眠1000毫秒。
注意:sleep()写在哪个线程,哪个线程就休眠
public class Test01 { public static void main(String[] args) { String[] names = {"高阳","苏楠","王智"}; Random ran = new Random(); int index = ran.nextInt(names.length); for (int i = 3; i >= 1; i--) { System.out.println(i); try { Thread.sleep(1000); } catch (InterruptedException e) { } if(i == 1){ System.out.println(names[index]); } } } }
需求:创建两个线程A,B,分别各打印1-100,其中B一个线程,每打印一次,就礼让一次,观察实验结果
Thread.yield(); --> 该方法写在哪个线程哪个线程就礼让(退出CPU资源)
注意:当前线程退出CPU资源后,又马上进入到抢资源的状态
public class Test01 { public static void main(String[] args) { //需求:创建两个线程A,B,分别各打印1-100,其中B一个线程,每打印一次,就礼让一次,观察实验结果 new A().start(); new B().start(); } } class A extends Thread{ @Override public void run() { for (int i = 1; i <= 100; i++) { System.out.println("A:" + i); } } } class B extends Thread{ @Override public void run() { for (int i = 1; i <= 100; i++) { System.out.println("B:" + i); Thread.yield();//礼让 } } }
需求:主线程和子线程各打印1-200,当主线程打印到10之后,让子线程先打印完再打印主线程
public class Test01 { public static void main(String[] args) { //需求:主线程和子线程各打印1-200,当主线程打印到10之后,让子线程先打印完再打印主线程 MyThread t = new MyThread(); t.start(); for (int i = 1; i <= 200; i++) { System.out.println("主线程:" + i); if(i == 10){ try { t.join();//合并:把此线程合并到当前线程 } catch (InterruptedException e) { } } } } } class MyThread extends Thread{ @Override public void run() { for (int i = 1; i <= 200; i++) { System.out.println("子线程:" + i); } } }
public class Test01 { public static void main(String[] args) throws InterruptedException { //中断线程 MyThread t = new MyThread(); t.start(); Thread.sleep(3000); t.interrupt();//改变线程状态 } } class MyThread extends Thread{ @Override public void run() { while(!Thread.currentThread().isInterrupted()){//获取当前线程状态 System.out.println("1"); System.out.println("2"); System.out.println("3"); System.out.println("4"); } } }
后台线程默默守护着非后台线程,非后台线程消亡后,后台线程会自动消亡
public class Test01 { public static void main(String[] args) throws InterruptedException { //后台线程 GuardThread guardThread = new GuardThread(); guardThread.setDaemon(true);//设置当前线程为后台线程 guardThread.start(); for (int i = 1; i <= 5; i++) { System.out.println("主线程:" + i); Thread.sleep(1000); } } } class GuardThread extends Thread{ @Override public void run() { while(true){ System.out.println("后台线程正在默默执行..."); try { Thread.sleep(1000); } catch (InterruptedException e) { } } } }
a) 新建状态
在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此时,它已经有了相应的内存空间和其它资源,但还处于不可运行状态。新建一个线程对象可采用线程构造方法来实现。
例如:Thread thread=new Thread();
b) 就绪状态
新建线程对象后,调用该线程的start()方法就可以启动线程。当线程启动时,线程进入就绪状态。此时,线程将进入线程队列排队,等待CPU调用,这表明它已经具备了运行条件。
c) 运行状态
当就绪状态的线程被调用并获得处理器资源时,线程就进入了运行状态。此时,自动调用该线程对象的run()方法。run()方法定义了该线程的操作和功能。
d) 阻塞状态
一个正在执行的线程在某些特殊情况下,如被人为挂起,将让出CPU并暂时中止自己的执行,进入阻塞状态。在可执行状态下,如果调用sleep(2000)、wait()等方法,线程都将进入阻塞状态。阻塞时,线程不能进入排队队列,只有当引起阻塞的原因被消除后,线程才可以转入就绪状态。
e) 死亡状态
线程调用stop()方法时或run()方法执行结束后,线程即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。