并行:指两个或多个时间在同一时刻发生(同时发生);
并发:指两个或多个事件在一个时间段内发生。
单核处理器的计算机肯定不能并行的处理多个任务,只能是多个任务交替的在单个 CPU 上运行。
Java 程序的进程里面至少包含两个线程,主进程也就是 main()方法线程,另外一个是垃圾回收机制线程。每当使用 java 命令执行一个类时,实际上都会启动一个 JVM,每一个 JVM 实际上就是在操作系统中启动了一个线程,java 本身具备了垃圾的收集机制,所以在 Java 运行时至少会启动两个线程。
常用的windows 应用软件命令
1、regedit:打开注册表编辑器
2、control:打开控制面板
3、msconfig:打开系统配置
4、gpedit.msc:打开本地组策略
5、explorer:打开资源管理器
6、taskmgr:任务管理器
7、logoff:直接注销计算机
8、osk:打开屏幕键盘
9、calc:打开计算器
10、mspaint:调出画图软件
11、dxdiag:查看电脑详细配置信息
12、mstsc:打开远程桌面连接
13、systeminfo:查看计算机基本信息
14、notepad:打开记事本
表示当前进程所在的虚拟机实例,每个Java应用程序都有一个Runtime类的Runtime ,允许应用程序与运行应用程序的环境进行接口。
由于任何进程只会运行与一个虚拟机实例当中,即只会产生一个虚拟机实例(底层源码采用 单例模式)
当前运行时可以从getRuntime方法获得
package com.alphabet.Process;import java.io.IOException;public class Process {/*** 用java打开记事本* @throws IOException*/public static void main(String[] args) throws IOException {Runtime run=Runtime.getRuntime();//使用Runtiome的exec方法run.exec("mspaint");//打开画板run.exec("notepad");//打开画板//ProcessBuilder的start方法ProcessBuilder pb=new ProcessBuilder("notepad");pb.start();}}源码可以看到,构造器私有化了,即外部我们不能 new 一个新的 Runtime 实例,而内部给了我们一个获取 Runtime 实例的方法 getRuntime() 。通过 ProcessBuilder 创建进程
package com.alphabet.Process;public class classA extends Thread{@Overridepublic void run() {//线程执行值// TODO Auto-generated method stubfor (int i = 0; i < 50; i++) {System.out.println("播放音乐第"+i+"首");}}public static void main(String[] args) {//创建线程方法(并启动线程)/*** 语法如下* classA a=new classA();* a.start;//启动一个线程* 不要调用run方法,如果调用run方法的话,好比调用普通方法。依然还是只有一个线程,并没有开启新的线程* java虚拟机在负责线程的调度问题,哪个线程执行完全取决于 CPU 的调度,* 程序员是干涉不了的。而这也就造成的多线程的随机性。*/for (int i = 0; i < 50; i++) {System.err.println("打游戏"+i);if(i==10) {//创建线程并启动线程classA a=new classA();a.start();}}}}
package com.alphabet.Process;public class SimpleRunnable implements Runnable {//SimpleRunnable不是线程类@Overridepublic void run() {// TODO Auto-generated method stubSystem.out.println("请开始你的表演");}public static void main(String[] args) {SimpleRunnable target=new SimpleRunnable();Thread t=new Thread(target);t.start();}}package com.alphabet.Process;public class classB {public static void main(String[] args) {for(int i = 0 ; i < 10 ; i++){System.out.println("玩游戏"+i);if(i==5){new Thread(new Runnable() {@Overridepublic void run() {for(int i = 0 ; i < 10 ;i++){System.out.println("播放音乐"+i);}}}).start();}}}}
1、新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new Thread();
2、就绪状态(Runnable):也被称为“可执行状态”。当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
3、运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
4、阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
(1)等待阻塞 -- 运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
(2)同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
(3)其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
线程的优先级:优先级的范围在1-10,默认值为5;可以使用Thread类中setPriority()方法来设定,但必须在1-10以内,不然会报错。优先权教高的,会被提前执行,当他执行完成才会轮到优先权较低的线程执行。如果优先权相同,那么采用轮流执行的方式.但是,线程优先级不能保证线程执行的顺序。
如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
改变线程名称,使之与参数 name 相同。
更改线程的优先级。
将该线程标记为守护线程或用户线程。
等待该线程终止的时间最长为 millis 毫秒。
中断线程。
测试线程是否处于活动状态。
暂停当前正在执行的线程对象,并执行其他线程。
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
返回对当前正在执行的线程对象的引用。
将当前线程的堆栈跟踪打印至标准错误流。
互斥条件:一个资源每次只能被一个进程使用。独木桥每次只能通过一个人。
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。乙不退出桥面,甲也不退出桥面。
不剥夺条件: 进程已获得的资源,在未使用完之前,不能强行剥夺。甲不能强制乙退出桥面,乙也不能强制甲退出桥面。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。如果乙不退出桥面,甲不能通过,甲不退出桥面,乙不能通过。