java thread_Java(多线程Thread)
畢設(shè)遇到些問題,猜想可能與多線程有關(guān)聯(lián),所以花了幾天時(shí)間學(xué)習(xí)了多線程,在此小結(jié)一番
1.進(jìn)程與多進(jìn)程
一個(gè)進(jìn)程對(duì)應(yīng)一個(gè)應(yīng)用程序。在java的開發(fā)環(huán)境下啟動(dòng)JVM,就表示啟動(dòng)了一個(gè)進(jìn)程。在同一個(gè)操作系統(tǒng)中,可以啟動(dòng)多個(gè)進(jìn)程
對(duì)于單核計(jì)算機(jī)來講,在同一個(gè)時(shí)間點(diǎn)上運(yùn)行了游戲進(jìn)程和音樂進(jìn)程,但實(shí)際二者并不是同時(shí)運(yùn)行
而計(jì)算機(jī)的CPU在某個(gè)時(shí)間點(diǎn)上只能做一件事,所以計(jì)算機(jī)在 游戲進(jìn)程 和 音樂進(jìn)程 之間頻繁的切換執(zhí)行,由于切換速度極高,所以人類感覺兩者在同時(shí)進(jìn)行
多進(jìn)程的作用不是提高執(zhí)行速度,而是提高CPU的使用率
進(jìn)程和進(jìn)程之間的內(nèi)存是獨(dú)立的
2.線程與多線程
線程是一個(gè)進(jìn)程中的執(zhí)行場(chǎng)景。一個(gè)進(jìn)程可以啟動(dòng)多個(gè)線程
多線程作用不是為了提高執(zhí)行速度,而是提高應(yīng)用程序的使用率
線程和線程共享“堆內(nèi)存和方法區(qū)內(nèi)存”,棧內(nèi)存是獨(dú)立的,一個(gè)線程一個(gè)棧
由于多線程在來回切換,所以給現(xiàn)實(shí)世界中的人類一種錯(cuò)覺:感覺多個(gè)線程在同時(shí)并發(fā)執(zhí)行。
3.關(guān)于Java程序的運(yùn)行原理
java命令會(huì)啟動(dòng)JVM,等于啟動(dòng)了一個(gè)應(yīng)用程序即進(jìn)程,該進(jìn)程會(huì)自動(dòng)啟動(dòng)一個(gè)主線程,然后主線程去調(diào)用某個(gè)類的main方法,所以main方法運(yùn)行在主線程中
4.在Java語言中實(shí)現(xiàn)多線程的兩種方式
第一種:
繼承 java.lang.Thread
重寫 run 方法
class Processor extends Thread{
public void run(){
System.out.println("helloworld");
}
}
第二種:
實(shí)現(xiàn) java.lang.Runnable
實(shí)現(xiàn) run 方法
class Processor1 implements Runnable{
public void run(){
System.out.println("helloworld");
}
}
5.UML圖描述線程的生命周期
JVM
6.線程的調(diào)度與控制
CPU在某個(gè)時(shí)刻只能執(zhí)行一條指令,線程只有得到CPU時(shí)間片,才能執(zhí)行命令
JVM負(fù)責(zé)線程的調(diào)度,取得CPU的時(shí)間片。優(yōu)先級(jí)高的線程獲取的CPU時(shí)間片相對(duì)多一些
ThreadTest01.java
Thread t1 = new Processor();//創(chuàng)建線程
t1.setName("t1");//給線程起名
t1.setPriority(5);//設(shè)置優(yōu)先級(jí)(由低到高1~10)
Thread t2 = new Processor();
t2.setName("t1");
t2.setPriority(10);
t1.start();//告訴JVM再分配一個(gè)新的棧給t線程,run不需程序員手動(dòng)調(diào)用
t2.start();//系統(tǒng)線程啟動(dòng)后自動(dòng)調(diào)用run方法
7.線程阻塞(sleep)與終止(interrupt)
Thread.sleep(ms),是一個(gè)靜態(tài)方法,阻塞當(dāng)前線程,騰出CPU,讓給其他線程
ThreadTest02.java
//依靠異常處理機(jī)制,3s后打斷線程的休眠
public class ThreadTest02 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(new Processor4());
t.setName("t");
t.start();
Thread.sleep(3000);
t.interrupt();//打斷t的休眠
}
}
class Processor4 implements Runnable{
@Override
public void run() {
try {Thread.sleep(100000);} catch (InterruptedException e) {}
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
}
ThreadTest03.java
//需求:更好的終止一個(gè)正在執(zhí)行的線程
public class ThreadTest03 {
public static void main(String[] args) throws InterruptedException {
Processor5 p =new Processor5();
Thread t=new Thread(p);
t.setName("t5");
t.start();
Thread.sleep(5000);
p.run=false;//終止
}
}
class Processor5 implements Runnable{
boolean run = true;//利用Boolean來控制
@Override
public void run() {
for(int i=0;i<10;i++){
if(run){
try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println(Thread.currentThread().getName()+"-->"+i);
}else{
return;//結(jié)束此方法
}
}
}
}
8.線程的同步(加鎖)important!
異步編程模型:t1線程執(zhí)行t1的,t2線程執(zhí)行t2的,兩線程之間誰也不等誰
同步編程模型:t1線程和t2線程執(zhí)行,t1必須等t2線程執(zhí)行結(jié)束后才能執(zhí)行
為什么要引入線程同步呢?
為了數(shù)據(jù)的安全。盡管應(yīng)用程序的使用率降低,但是為了保證數(shù)據(jù)是安全的,必須加入線程同步機(jī)制。(線程同步機(jī)制讓程序等同于單線程)
什么條件下要使用線程同步?
必須是多線程環(huán)境
多線程環(huán)境共享同一個(gè)數(shù)據(jù)
共享的數(shù)據(jù)涉及到修改操作
模擬銀行取款場(chǎng)景(synchronized關(guān)鍵字也可直接添加到成員方法上)
原理:T1線程執(zhí)行到此處遇到synchronized關(guān)鍵字,就會(huì)去找this的對(duì)象鎖,找到則進(jìn)入同步語句塊執(zhí)行程序,執(zhí)行完再歸還對(duì)象鎖
在T1線程執(zhí)行同步語句塊的過程中,若T2線程執(zhí)行到此處也遇到synchronized關(guān)鍵字,但未找到this的對(duì)象鎖,只能等待T1歸還
(synchronized添加到靜態(tài)方法上,線程執(zhí)行此方法時(shí)會(huì)找類鎖)
public void withdraw(double money){
//把需要同步的代碼放到同步語句塊中
synchronized(this){
double after = balance - money;
//延遲
try{Thread.sleep(1000);}catch(InterruptedException e){}
//更新
this.setBalance(after);
}
}
9.死鎖(DeadLock)
public class DeadLock {
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
Thread t1 = new Thread(new T1(o1,o2));
Thread t2 = new Thread(new T2(o1,o2));
t1.start();
t2.start();
}
}
class T1 implements Runnable{
Object o1;
Object o2;
T1(Object o1,Object o2){
this.o1=o1;
this.o2=o2;
}
public void run() {
synchronized(o1){
try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
synchronized(o2){}
}
}
}
class T2 implements Runnable{
Object o1;
Object o2;
T2(Object o1,Object o2){
this.o1=o1;
this.o2=o2;
}
public void run() {
synchronized(o2){
try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
synchronized(o1){}
}
}
}
總結(jié)
以上是生活随笔為你收集整理的java thread_Java(多线程Thread)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: uilabel 自行撑开高度_UILab
 - 下一篇: 提示重置失败未做更改怎么办 重置失败未做