1.一個進程對應一個應用程序
2.多進程有什么作用诅挑?
單進程的計算機只能做一件事
計算機的CPU是能在某個時間點上做一件事
單核、雙核泛源、四核實現真正意義的同時處理
多進程的作用不是提高執(zhí)行速度拔妥,而是提高CPU的使用率!4锕俊C涣!!
進程和進程之間的內存是獨立的硬纤。比如游戲和音樂的內存
3.什么是線程解滓?
線程是一個進程的執(zhí)行場景。一個進程可以啟動多個線程
4.多線程有什么作用筝家?
多線程的作用不是提高執(zhí)行速度伐蒂,而是提高應用程序的使用率。
服務器-多個客戶端
提高該應用程序的使用率
看似同時運行肛鹏,其實有切換的環(huán)節(jié)的逸邦。
線程和線程共享“堆內存和方法區(qū)內存”,棧內存是獨立的在扰,一個線程一個棧缕减。
5.java程序的運行原理?
java命令會啟動java虛擬機芒珠,啟動JVM桥狡,等于啟動了一個應用程序,表示啟動了一個進程皱卓。該進程會自動啟動一個“主線程”裹芝,然后主線程去調用某個類的main方法。所以方法運行在主線程中娜汁。在其之前的所有程序都是單線程的嫂易。
JVM-->進程-->主線程-->main-->單線程
public class test01 {
public static void main(String[] args){
m1();
}
public static void m1(){
m2();
}
public static void m2(){
m3();
}
public static void m3(){
System.out.println("m3.....");
}
}
也是單線程的,只開辟一塊椘空間怜械。后進先出。只有主線程傅事。缕允。。蹭越。
6.在java中實現多線程的方法
繼承java.lang.Thread;
重寫覆蓋run();(不重寫并不會報錯障本,知識新啟動的線程什么都不做)
如何創(chuàng)建線程?
如何啟動線程响鹃?
Thread t = new Processor();//父類引用指向子類對象
t.start();
/**
*
*/
public class test01 {
public static void main(String[] args){
Thread t = new Processor();
//Processor t = new Processor();
t.start();
//并不是像常規(guī)的程序一樣在主線程棧中壓棧
for(int i = 0; i < 100; i++){
System.out.println("main-->" + i);
}
}
}
class Processor extends Thread{
public void run(){
for(int i = 0; i < 100; i++){
System.out.println("run-->" + i);
}
}
}
<--------------------------------------------->
寫一個類實現java.lang.Runnable;接口
實現run方法
public class test01 {
public static void main(String[] args) {
//創(chuàng)建線程
Thread t = new Thread(new Processor());
//啟動
t.start();
for (int i = 0; i < 100; i++)
System.out.println("main-->" + i);
}
}
/**
Processor()可運行的驾霜,Thread所有已實現的接口里有Runnable接口,也是可運行的
*/
class Processor implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++)
System.out.println("run-->" + i);
}
}
總結:
目前我知道的實現多線程有兩種方式茴迁,一種是繼承Thread類寄悯,重寫run方法。
首先定義線程Processor繼承Thread類堕义,然后主方法中創(chuàng)建線程,Thread t = new Processor();父類引用指向子類對象,然后t.start();
第二種是實現Runnable接口倦卖,實現run方法洒擦。
首先定義Processor實現Runnable接口,實現run方法怕膛,然后主方法創(chuàng)建線程熟嫩,Thread t = new Thread(new Processor());將new Processor()對象傳給Thread。然后t.start()褐捻。
推薦選擇第二種掸茅。
因為一個類實現接口之外還保留了類的繼承
7.線程的生命周期
新建
就緒
運行
阻塞
死亡/消亡
- new表示新建狀態(tài)
- 線程新建之后調用start方法進入就緒狀態(tài)
就緒狀態(tài)的線程表示有權利去獲取CPU的時間片。CPU時間片是執(zhí)行權柠逞。當線程拿到CPU時間片之后就馬上執(zhí)行run方法昧狮,這個時候就代表進入運行狀態(tài)。(就緒狀態(tài)和運行狀態(tài)頻繁切換) - 阻塞事件導致運行到阻塞
-
阻塞解除導致阻塞到運行
線程的生命周期.jpg
8.線程的調度與控制
java虛擬機負責線程的調度板壮,取得CPU的使用權逗鸣。
目前兩種調度模型:分時調度模型、搶占式調度模型
搶占式調度模型:優(yōu)先級高的線程獲取的時間片相對多一些绰精,有時候也不一定
8.1線程優(yōu)先級
1-10 默認是5
MAX_PRIORITY MIN_PRIORITY NOM_PRIORITY 最高級 最低級 默認
/**
*線程優(yōu)先級
* 如何獲得線程對象
*
*/
public class test01 {
public static void main(String[] args) {
Thread t = Thread.currentThread();
//static Thread currentThread()
//返回對當前正在執(zhí)行的對象的引用
//t保存的的內存地址指向的線程是“主線程對象”
System.out.println(t.getName());//main
Thread t1 = new Thread(new Processor());
t1.setName("t1");
t1.start();//t1
Thread t3 = Thread.currentThread();
System.out.println(t3.getName()); //main
Thread t2 = new Thread(new Processor());
t2.setName("t2");
t2.start();//t2
}
}
class Processor implements Runnable {
@Override
public void run() {
Thread t = Thread.currentThread();
System.out.println(t.getName());
}
}
/**
*線程優(yōu)先級
* 如何獲得線程對象
*
*/
public class test01 {
public static void main(String[] args) {
Thread t = Thread.currentThread();
//static Thread currentThread()
//返回對當前正在執(zhí)行的對象的引用
//t保存的的內存地址指向的線程是“主線程對象”
System.out.println(t.getName());//main
Thread t1 = new Thread(new Processor());
t1.setName("t1");
Thread t2 = new Thread(new Processor());
t2.setName("t2");
t1.setPriority(10);
t2.setPriority(1);
t1.start();//t1
t2.start();//t2
}
}
class Processor implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--->" + i);
}
}
}
8.2
Thread.sleep();
sleep方法是一個靜態(tài)方法
作用:阻塞當前線程撒璧,騰出CPU,讓給其他程序
import static java.lang.Thread.*;
public class test01 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Processor());
t.start();
for (int i = 0; i < 10; i++) {
System.out.println(currentThread().getName() + "-->" + i);
sleep(1000);
}
}
}
class Processor implements Runnable {
@Override
//老師講的是繼承Thread笨使,下面的注釋和我寫的不一致卿樱,但是也會遇到同樣的問題,為什么硫椰?殿如??最爬?涉馁?
//Thread中的run方法不拋出異常,所以重寫run方法之后爱致,在run方法的聲明位置不能throws
//只能try...catch...
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(currentThread().getName() + "-->" + i);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//import static java.lang.Thread.currentThread;
public class test01 {
public static void main(String[] args) throws InterruptedException {
A a = null;
a.m1();
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName() + "Hello World");
//System.out.println(currentThread().getName() + "Hello World"); 這種寫法需導入import static java.lang.Thread.currentThread;
//我不知道為什么
}
}
class A{
public static void m1(){}
}
以上程序涉及到兩個問題烤送,一個待解決
t.interrupt();不是靜態(tài)方法 作用時結束睡眠
//import static java.lang.Thread.currentThread;
public class test01 {
public static void main(String[] args) throws InterruptedException {
boolean run = true;
Processor p = new Processor();
Thread t = new Thread(p);
t.setName("T");
t.start();
Thread.sleep(5000);
p.run = false;
}
}
class Processor implements Runnable{
boolean run = true;
public void run(){
long timeStart = System.currentTimeMillis();
for(int i = 0; i < 10 && (System.currentTimeMillis() - timeStart) <= 5000; i++){//我用兩種方式進行了控制
System.out.println(Thread.currentThread().getName() + "-->" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thread.yield
讓位
她與sleep()類似,只是不能由用戶指定暫時的時間糠悯,而且只能同優(yōu)先級的線程讓位帮坚,但是讓位時間不固定。
和sleep()一樣都是靜態(tài)方法
線程的合并
t.join() 是成員的方法;グJ院汀!纫普!
8.3