java隋唐演义游戏下载_JAVA多线程
第一節(jié) 多線程背景知識(shí)介紹
多線程作用:可以幫助簡(jiǎn)化模型,還能編寫強(qiáng)大的代碼。進(jìn)程與線程的基礎(chǔ)概念:Eclipse QQ都屬于進(jìn)程。進(jìn)程是程序(任務(wù))的執(zhí)行過程,它持有資源(共享內(nèi)存、共享文件)和線程。它包含兩點(diǎn):1.動(dòng)態(tài)性,雙擊運(yùn)行之后這才稱之為進(jìn)程,它是動(dòng)態(tài)的概念;2.持有資源和線程,資源就是內(nèi)存和文件。進(jìn)程是資源的載體,也是線程的載體。脫離進(jìn)程去談?wù)摼€程就沒有什么意義了。資源就是我們所說的內(nèi)存,我們知道程序是需要從內(nèi)存中讀取數(shù)據(jù)進(jìn)行運(yùn)行的,所以每個(gè)進(jìn)程執(zhí)行的時(shí)候都會(huì)被分配一個(gè)內(nèi)存。那么線程是是什么呢?當(dāng)你運(yùn)行Eclipce你要進(jìn)行一些任務(wù),比如你要在文本編輯區(qū)編寫源代碼,我們的Eclipce會(huì)自動(dòng)在后臺(tái)編譯我們的源代碼,有的代碼還有語法效驗(yàn),再看QQ聊天,發(fā)文件,所有這些任務(wù)我們都可以把他們理解成線程。如果把進(jìn)程比作一個(gè)班級(jí),可以把每個(gè)學(xué)生比作一個(gè)線程,學(xué)生是班級(jí)中的最小單元。一個(gè)班級(jí)可以有多個(gè)學(xué)生,他們都使用班級(jí)中共同的板凳、桌椅、黑板、粉筆等來進(jìn)行他們的學(xué)習(xí)生活。這個(gè)意義上我們說線程是系統(tǒng)中最小的執(zhí)行單元,同一個(gè)進(jìn)程中可以有多個(gè)線程,線程共享進(jìn)程的資源。
線程的交互:如一個(gè)班級(jí)中的學(xué)生一樣,我們說多個(gè)線程需要通信才能正確的工作,這種通信我們把它稱之為線程的交互。交互的方式包括互斥和同步。將概念類比到班級(jí)中,我們的同學(xué)之間需要通過相互的協(xié)會(huì)來完成某些任務(wù),有時(shí)這些協(xié)作是需要競(jìng)爭(zhēng)的。比如學(xué)習(xí),班級(jí)的公共資源是有限的,愛學(xué)習(xí)的同學(xué)需要搶占,需要競(jìng)爭(zhēng),一個(gè)同學(xué)用完了下一個(gè)同學(xué)才能使用,如果一個(gè)同學(xué)正在使用,那么其他新來的同學(xué)只能等待。另一方面我們又需要同步或者協(xié)作,好比班級(jí)六一需要排演一個(gè)節(jié)目,全班同學(xué)齊心協(xié)力,相互配合,才能把節(jié)目完美的呈現(xiàn)在學(xué)校面前,這些就是線程的交互。
第二節(jié) JAVA線程初體驗(yàn)
JAVA線程中常用方法介紹:1.java對(duì)線程的支持;2.如何用java創(chuàng)建并啟動(dòng)線程;3.線程常用的方法和那些含義;4.如何停止線程。
java語言對(duì)線程的支持,主要體現(xiàn)在class Thread 類里以及interface Runnable這個(gè)接口上,它們都寄生于java.lang包,無論是Thread這個(gè)類還是Runnable這個(gè)interface,里面都有一個(gè)共通的方法,就是我們的,public void run(),run方法為我們提供了線程實(shí)際工作執(zhí)行的代碼,一般都會(huì)復(fù)寫。
下面我們看看線程中常用的方法:
Thread常用方法
a.線程的創(chuàng)建
Thread()
Thread(String name)
Thread(Runnable target)
Thread(Runnable target,String name)
這四個(gè)是常用的線程構(gòu)造函數(shù)
b.線程的方法
void start() 啟動(dòng)線程
static void sleep(long millis)
static void sleep(long millis,int nanos)
可以讓線程休眠指定的時(shí)間,millis毫秒,nanos納秒
void join()
void join(long millis)
void join(long millis,int nanos)
調(diào)用線程,可以讓其他線程等待自己運(yùn)行,直到結(jié)束。
這里第一個(gè)方法沒有參數(shù),其它的線程一定要等待我們的執(zhí)行線程執(zhí)行完畢之后才會(huì)獲得運(yùn)行的機(jī)會(huì),帶參數(shù)的則指明了一個(gè)時(shí)間閾值,最長(zhǎng)需要等待的時(shí)間,這個(gè)時(shí)間單位是毫秒,我們可以通過第二個(gè)參數(shù)將時(shí)間精確到納秒
static void yield()
當(dāng)前正在運(yùn)行的線程釋放處理器資源并重新去競(jìng)爭(zhēng)處理器資源
static Thread currentThread()
返回當(dāng)前正在處理器上運(yùn)行的線程的引用
第三節(jié) JAVA線程-隋唐演義框架說明
1.設(shè)計(jì)一個(gè)隋唐演義程序來模擬線程的執(zhí)行,首先是隋唐之間的農(nóng)民戰(zhàn)爭(zhēng),一定會(huì)有戰(zhàn)爭(zhēng)的軍隊(duì),用對(duì)象來分別模擬我們的隋朝軍隊(duì)和農(nóng)民起義軍。因?yàn)殡p方軍隊(duì)的戰(zhàn)爭(zhēng)行為都是各自實(shí)行的,所以我們用Runnable對(duì)象可以非常輕而易舉的隔離雙方的差異,使其各自為戰(zhàn),以便于我們抽象實(shí)現(xiàn)。
//軍隊(duì)線程
//模擬作戰(zhàn)雙方的行為
public class ArmyRunnable implements Runnable{
ArmyRunnable armyTaskOfSuiDynasty=new ArmyRunnable();
ArmyRunnable armyTaskOfRevolt=new ArmyRunnable();
//army 陸軍 軍隊(duì);Task 任務(wù) 工作;Of 屬于;Dynasty 王朝 Revolt 反叛
//完成上面的任務(wù)等于是建立了兩個(gè)軍隊(duì)的對(duì)象,然后創(chuàng)建線程
public void run(){}
//復(fù)寫run方法
}
//使用Runnable接口創(chuàng)建線程
Thread armyOfSuiDynasty=new Thread(armyTaskOfSuiDynasty,"隋軍");
Thread armyOfRevolt=new Thread(armyTaskOfRevolt,"農(nóng)民軍");
2.英雄人物可以推動(dòng)歷史發(fā)展,關(guān)鍵人物的線程來模擬英雄人物
public class KeyPersonThread extends Thread{
public void run(){
//復(fù)寫run方法
//輸出某軍名字+開始戰(zhàn)斗 可以用Thread.currentThread().getName
}
}
3.需要有一個(gè)舞臺(tái)線程,把所有元素融合進(jìn)來 class Stage extends Thread
第四節(jié) 隋唐演義實(shí)戰(zhàn)開發(fā)I
這里我們首先先實(shí)驗(yàn)下Thread類和Runnable類的使用,假如我們的演員是兩個(gè)人,Mr.Thread 和Ms.Runnable,Thread先生和Runnable小姐,讓他們交替上臺(tái)表演。后面貼代碼
這里先把學(xué)習(xí)的經(jīng)驗(yàn)總結(jié)一下:
每一個(gè)java文件中只能有一個(gè)public類,直接在當(dāng)前類的末尾新建其它類也可以,但是不能寫public,這里所說的不是內(nèi)部類是獨(dú)立的外部類,當(dāng)然直接新建一個(gè)java文件單獨(dú)建類或者直接class 類名都可以。
兩種方法實(shí)現(xiàn)線程:
1、繼承 Thread 類
class MyThread extends Thread{};
Thread myThread = new MyThread();
myThread.start();
2、實(shí)現(xiàn)Runnable接口
class MyRunnable implements Runnable{}
Thread myRunnable = new Thread(new MyRunnable);
myRunnable.start();
3、Thread啟動(dòng)后執(zhí)行run()方法
4、若實(shí)現(xiàn)接口通過Thread.currentThread().getName()方法獲取當(dāng)前線程名稱,繼承Thread則getName()方法獲取當(dāng)前線程。
Thread類的方法:
.getName() 返回線程的名字
.setName(String Name) 改變線程的名字
.start() 使該線程開始執(zhí)行,Java 虛擬機(jī)調(diào)用該線程的 run 方法。
.sleep(long millis) 在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行),此操作受到系統(tǒng)計(jì)時(shí)器和調(diào)度程序精度和準(zhǔn)確性的影響。線程不丟失任何監(jiān)視器的所屬權(quán)。
.currentThreat() 返回對(duì)當(dāng)前正在執(zhí)行的線程對(duì)象的引用。(靜態(tài)方法,返回Thread類型)
package actor;
/**
* Created by Administrator on 2017/4/6.
*/
//創(chuàng)建一個(gè)類繼承自Thread類。
public class Actor extends Thread {
//在我們的類中復(fù)寫我們的run()方法
public void run(){
//這里調(diào)用getName()方法來獲得我們當(dāng)前線程的名稱
System.out.println(getName()+"是一個(gè)演員!");
//給出一個(gè)計(jì)數(shù)器來顯示線程先生出場(chǎng)演出了多少次
int count=0;
boolean keepRunning=true;
while(keepRunning){
System.out.println(getName()+"登臺(tái)演出了:"+(++count));
if(count==100){
keepRunning=false;
}
if(count%10==0){
try {
//每演出10場(chǎng)后,停頓休眠1S
Thread.sleep(1000);
//millis是毫秒,1S=1000millis
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//這里使用count++和++count輸出的結(jié)果不同,后者是1,前者是0
System.out.println(getName()+"的演出結(jié)束了!");
}
public static void main(String[] args) {
Thread actor=new Actor();
//這里我們可以看到 父類的引用指向了子類的實(shí)例,多態(tài)
//換成Actor程序一樣可以運(yùn)行
actor.setName("Mr.Thread");
//調(diào)用setName()方法給線程設(shè)置名字
actor.start();
//調(diào)用.start方法開始線程
Thread actressThread=new Thread(new Actress(),"Ms.Runnable");
//我們有了第二個(gè)類,可以創(chuàng)建一個(gè)新的對(duì)象,調(diào)用Thread類的構(gòu)造函數(shù)
// 通過接收我們實(shí)現(xiàn)了Runnable接口的對(duì)象來創(chuàng)建線程,或者也可以調(diào)用
//setName也沒有問題
actressThread.start();
}
}
//在actor類后新建一個(gè)類,注意在我們的.java文件中,可以有多個(gè)類,但是只能
//有一個(gè)public類這里所說的不是內(nèi)部類,而都是一個(gè)獨(dú)立的外部類。
//或者單獨(dú)新建一個(gè)類也可以,這都沒有任何問題
class Actress implements Runnable{
@Override
public void run() {
//這里復(fù)制上面的方法調(diào)用getName(),但由于Runnable中
// 沒有g(shù)etName方法,所以我們要用Thread.currentThread()
// 來獲取當(dāng)前線程的引用,來獲得我們當(dāng)前線程的名稱
System.out.println(Thread.currentThread().getName()+"是一個(gè)演員!");
//給出一個(gè)計(jì)數(shù)器來顯示線程先生出場(chǎng)演出了多少次
int count=0;
boolean keepRunning=true;
while(keepRunning){
System.out.println(Thread.currentThread().getName()+"登臺(tái)演出了:"
+(++count));
if(count==100){
keepRunning=false;
}
if(count%10==0){
try {
//每演出10場(chǎng)后,停頓休眠1S
Thread.sleep(1000);
//millis是毫秒,1S=1000millis
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//這里使用count++和++count輸出的結(jié)果不同,后者是1,前者是0
System.out.println(Thread.currentThread().getName()+"的演出結(jié)束了!");
}
}
//作為計(jì)算機(jī)處理器CPU或者同一個(gè)核同時(shí)只能運(yùn)行一條線程
//當(dāng)我們的一條線程休眠之后,另外一條線程才獲得了我們的處理器時(shí)間
//這就是我們兩個(gè)演員交替演出的情況
第五節(jié) 隋唐演義實(shí)戰(zhàn)開發(fā)II
package threadInImooc;
/**
* Created by Administrator on 2017/4/6.
* 軍隊(duì)任務(wù)線程,模擬作戰(zhàn)雙方的行為
*/
public class ArmyRunnable implements Runnable {
volatile boolean keepRunning=true;
//volatile 是java的一個(gè)關(guān)鍵字,必須將keepRunnings聲明設(shè)置為volatile類型
//保證了線程可以正確讀入其他線程寫入的值。
//軍隊(duì)必須在得到命令之前持續(xù)的保持進(jìn)攻的態(tài)勢(shì),那么是誰來下達(dá)關(guān)鍵的命令,
//英雄人物也好,舞臺(tái)策劃也好是有外部的一個(gè)線程來告訴我們軍隊(duì)的線程你們應(yīng)該
//停止攻擊了,我們應(yīng)該轉(zhuǎn)入其他環(huán)節(jié),這個(gè)時(shí)候我們就寫入keepRunning的值
//如果不聲明由于可見性的問題,我們的當(dāng)前線程有可能不能正確的讀到這個(gè)值。
//關(guān)于可見性我們可以參考我們的, ref JMM java內(nèi)存模型,里面詳細(xì)的講述了
//什么是happens-before原則,以及為什么這個(gè)關(guān)鍵詞解決了這個(gè)可見性問題
//軍隊(duì)線程,模擬作戰(zhàn)雙方的行為
@Override
public void run() {
//當(dāng)填入keepRunning之后,按住Alt+Enter(eclipce應(yīng)該是ctrl+1)
//選擇create field keepRunning,keepRunning作為一個(gè)開關(guān),
//沒有收到停止時(shí)就繼續(xù)作戰(zhàn)
while(keepRunning){
//每次攻擊都會(huì)發(fā)送五連擊
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+
"進(jìn)攻對(duì)方"+"["+i+"]");
//提供當(dāng)前進(jìn)攻批次的信息
//我們通過一些技術(shù)手段可以使他們更公平的競(jìng)爭(zhēng)使得對(duì)手還有還手的機(jī)會(huì)
Thread.yield();//釋放當(dāng)前線程的處理器資源,并重新去競(jìng)爭(zhēng)處理器資源
//讓出了處理器時(shí)間下次誰進(jìn)攻還不一定了
}
}
System.out.println(Thread.currentThread().getName()+"結(jié)束戰(zhàn)斗了!");
}
}
package threadInImooc;
/**
* Created by Administrator on 2017/4/6.
*隋唐演義的大戲舞臺(tái)
*/
public class Stage extends Thread {
public void run(){
//利用軍隊(duì)線程引入我們的軍隊(duì)
ArmyRunnable armyTaskOfSuiDynast=new ArmyRunnable();
//隋軍作戰(zhàn)任務(wù)對(duì)象
ArmyRunnable armyTaskOfRevolt=new ArmyRunnable();
//農(nóng)民起義軍作戰(zhàn)任務(wù)對(duì)象
Thread armyOfSuiDynast=new Thread(armyTaskOfSuiDynast,"隋軍");
//創(chuàng)建軍隊(duì)線程隋軍
Thread armyOfRevolt=new Thread(armyTaskOfRevolt,"農(nóng)民起義軍");
//創(chuàng)建軍隊(duì)線程起義軍
//啟動(dòng)線程,調(diào)用兩個(gè)線程的start方法,讓軍隊(duì)開始作戰(zhàn)。
armyOfRevolt.start();
armyOfSuiDynast.start();
//大家知道戰(zhàn)爭(zhēng)細(xì)節(jié)宏大我們觀眾不希望被其他細(xì)節(jié)所打擾,所以讓舞臺(tái)線程
//暫時(shí)休眠。
//舞臺(tái)線程休眠50毫秒,大家專心看軍隊(duì)廝殺
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
armyTaskOfSuiDynast.keepRunning=false;
armyTaskOfRevolt.keepRunning=false;
try {
armyOfRevolt.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Stage().start();
}
}
第六節(jié) 隋唐演義實(shí)戰(zhàn)開發(fā) III
軍隊(duì)線程:
package threadInImooc;
/**
* Created by Administrator on 2017/4/6.
* 軍隊(duì)任務(wù)線程,模擬作戰(zhàn)雙方的行為
*/
public class ArmyRunnable implements Runnable {
volatile boolean keepRunning=true;
//volatile 是java的一個(gè)關(guān)鍵字,必須將keepRunnings聲明設(shè)置為volatile類型
//保證了線程可以正確讀入其他線程寫入的值。
//軍隊(duì)必須在得到命令之前持續(xù)的保持進(jìn)攻的態(tài)勢(shì),那么是誰來下達(dá)關(guān)鍵的命令,
//英雄人物也好,舞臺(tái)策劃也好是有外部的一個(gè)線程來告訴我們軍隊(duì)的線程你們應(yīng)該
//停止攻擊了,我們應(yīng)該轉(zhuǎn)入其他環(huán)節(jié),這個(gè)時(shí)候我們就寫入keepRunning的值
//如果不聲明由于可見性的問題,我們的當(dāng)前線程有可能不能正確的讀到這個(gè)值。
//關(guān)于可見性我們可以參考我們的, ref JMM java內(nèi)存模型,里面詳細(xì)的講述了
//什么是happens-before原則,以及為什么這個(gè)關(guān)鍵詞解決了這個(gè)可見性問題
//軍隊(duì)線程,模擬作戰(zhàn)雙方的行為
@Override
public void run() {
//當(dāng)填入keepRunning之后,按住Alt+Enter(eclipce應(yīng)該是ctrl+1)
//選擇create field keepRunning,keepRunning作為一個(gè)開關(guān),
//沒有收到停止時(shí)就繼續(xù)作戰(zhàn)
while(keepRunning){
//每次攻擊都會(huì)發(fā)送五連擊
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+
"進(jìn)攻對(duì)方"+"["+i+"]");
//提供當(dāng)前進(jìn)攻批次的信息
//我們通過一些技術(shù)手段可以使他們更公平的競(jìng)爭(zhēng)使得對(duì)手還有還手的機(jī)會(huì)
Thread.yield();//釋放當(dāng)前線程的處理器資源,并重新去競(jìng)爭(zhēng)處理器資源
//讓出了處理器時(shí)間下次誰進(jìn)攻還不一定了
}
}
System.out.println(Thread.currentThread().getName()+"結(jié)束戰(zhàn)斗了!");
}
}
關(guān)鍵人物線程
/**
* Created by Administrator on 2017/4/6.
*/
public class KeyPersonThread extends Thread {
//定義了一個(gè)關(guān)鍵人物類,復(fù)寫run方法。
public void run(){
System.out.println(Thread.currentThread().getName()+"開始了戰(zhàn)斗!");
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+
"左突右殺,攻擊隋軍...");
}
System.out.println(Thread.currentThread().getName()+"結(jié)束了戰(zhàn)斗!");
}
}
舞臺(tái)線程
/**
* Created by Administrator on 2017/4/6.
*隋唐演義的大戲舞臺(tái)
*/
public class Stage extends Thread {
public void run(){
System.out.println("歡迎觀看隋唐演義");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("大幕徐徐拉開");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("話說隋朝末年,隋軍與農(nóng)民起義軍殺得昏天黑地...");
//利用軍隊(duì)線程引入我們的軍隊(duì)
ArmyRunnable armyTaskOfSuiDynast=new ArmyRunnable();
//隋軍作戰(zhàn)任務(wù)對(duì)象
ArmyRunnable armyTaskOfRevolt=new ArmyRunnable();
//農(nóng)民起義軍作戰(zhàn)任務(wù)對(duì)象
Thread armyOfSuiDynast=new Thread(armyTaskOfSuiDynast,"隋軍");
//創(chuàng)建軍隊(duì)線程隋軍
Thread armyOfRevolt=new Thread(armyTaskOfRevolt,"農(nóng)民起義軍");
//創(chuàng)建軍隊(duì)線程起義軍
//啟動(dòng)線程,調(diào)用兩個(gè)線程的start方法,讓軍隊(duì)開始作戰(zhàn)。
armyOfRevolt.start();
armyOfSuiDynast.start();
//大家知道戰(zhàn)爭(zhēng)細(xì)節(jié)宏大我們觀眾不希望被其他細(xì)節(jié)所打擾,所以讓舞臺(tái)線程
//暫時(shí)休眠。
//舞臺(tái)線程休眠50毫秒,大家專心看軍隊(duì)廝殺
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正當(dāng)雙方激戰(zhàn)正酣,半路殺出個(gè)程咬金");
Thread mrCheng=new KeyPersonThread();
mrCheng.setName("程咬金");
System.out.println("程咬金的理想就是結(jié)束戰(zhàn)爭(zhēng),使百姓安居樂業(yè)!");
//此時(shí)要開始這個(gè)線程,同時(shí)為了將關(guān)鍵人物的作用體現(xiàn)出來,先將另外兩邊
//的軍隊(duì)停止線程,也就是while循環(huán)停止,給true變false
armyTaskOfSuiDynast.keepRunning=false;
armyTaskOfRevolt.keepRunning=false;
//隋軍和農(nóng)民起義軍線程停止,停止線程的方法
//下達(dá)命令之后我們要讓我們的舞臺(tái)劇休眠一會(huì),這樣可以讓我們的軍隊(duì)
//確實(shí)執(zhí)行停戰(zhàn)命令
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 歷史大戲留給關(guān)鍵線程。
*/
mrCheng.start();
//在萬眾矚目之下,所有的線程都應(yīng)該等待我們的程先生,所以要調(diào)用
//join方法,所有線程等待程先生完成歷史使命
try {
mrCheng.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//假如把join方法注釋掉,就會(huì)出現(xiàn)舞臺(tái)線程的后兩句穿插輸出了,之后
//才執(zhí)行我們關(guān)鍵先生的線程。join在程序的結(jié)束非常有用
System.out.println("戰(zhàn)爭(zhēng)結(jié)束,人民安居樂業(yè),程先生實(shí)現(xiàn)了積極的人生理想" +
",為人民做出了貢獻(xiàn)!");
System.out.println("謝謝觀看隋唐演義,再見!");
}
public static void main(String[] args) {
new Stage().start();
}
}
總結(jié)
以上是生活随笔為你收集整理的java隋唐演义游戏下载_JAVA多线程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux nslookup命令安装,在
- 下一篇: jmeter里的连接数_Jmeter之连