日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java-多线程操作全(Thread)-Timer简单使用

發(fā)布時(shí)間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java-多线程操作全(Thread)-Timer简单使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?一、 多線程概念和作用

?線程指進(jìn)程中的一個(gè)執(zhí)行場(chǎng)景,也就是執(zhí)行流程,那么進(jìn)程和線程的區(qū)別是什么

? 1.每個(gè)進(jìn)程是一個(gè)應(yīng)用程序,都有獨(dú)立的內(nèi)存空間

? 2.同一個(gè)進(jìn)程中的線程共享其進(jìn)程中的內(nèi)存和資源

? (共享的內(nèi)存是堆內(nèi)存和方法內(nèi)存,棧內(nèi)存不共享,每個(gè)線程有自己的堆內(nèi)存)

?進(jìn)程:進(jìn)程對(duì)應(yīng)一個(gè)應(yīng)用程序

? 現(xiàn)在的計(jì)算機(jī)都是支持多進(jìn)程的,在同一個(gè)操作系統(tǒng)中,可以同時(shí)啟動(dòng)多個(gè)進(jìn)程?

??

?多進(jìn)程的作用:

?* 單進(jìn)程只能做一件事 : 一邊玩游戲,一邊聽音樂不是同時(shí)運(yùn)行,而是進(jìn)程之間的頻繁調(diào)度,切換速度極高,感覺是同時(shí)進(jìn)行。

?* 多線程的作用不是提高執(zhí)行速度,而是提高CPU的使用率。進(jìn)程和進(jìn)程之間的內(nèi)存是獨(dú)立的、

?* 線程:是進(jìn)程中的執(zhí)行場(chǎng)景。一個(gè)進(jìn)程可以啟動(dòng)多個(gè)線程。

?* 多線程的作用:不是為了提高執(zhí)行速度,而是為了提高應(yīng)用程序的使用率

?

?* java程序的運(yùn)行原理

?* java命令啟動(dòng)java虛擬機(jī),啟動(dòng)JVM,等于啟動(dòng)一個(gè)應(yīng)用程序,表明啟動(dòng)一個(gè)進(jìn)程。該進(jìn)程會(huì)自動(dòng)啟動(dòng)一個(gè)“主線程”,然后主線程去調(diào)用某各類的main方法。

?* 所以,main方法運(yùn)行在主線程中。在此之前的所有程序都是單線程的。

?

?二、線程的創(chuàng)建和啟動(dòng)

?

?*Java虛擬機(jī)的主線程入口是main方法,用戶可以自己創(chuàng)建線程,創(chuàng)建方式有兩種

?*1.繼承Thread類

?*2.實(shí)現(xiàn)Runnable接口(推薦使用Runnable)

?

?*繼承Thread類

?*采用 Thread類創(chuàng)建線程,用戶只需要繼承 Thread,覆蓋 Thread中的run方法,父類 Thread中的run方法沒有拋出異常,那么子類也不角能拋出異常,最后采用start啟動(dòng)線程即可

?

?實(shí)現(xiàn)Runnable接口

?Thread對(duì)象本身就實(shí)現(xiàn)了 Runnable接口,但一般建議直接使用 Runnable接口來寫多線程程序,因?yàn)榻涌跁?huì)比類帶來更多的好處

?

三、java語言中實(shí)現(xiàn)多線程第一種方式

?

1.繼承java.lang.Thread

2.重寫run方法

三個(gè)知識(shí)點(diǎn) :定義線程 、創(chuàng)建線程、?啟動(dòng)線程

package com.steven.demo;import java.lang.Thread; public class ThreadTest {public static void main(String[] args) {Thread thread = new Student();//啟動(dòng)線程thread.start();//打印Run:0~9//start方法執(zhí)行完瞬間結(jié)束,告訴JVM再分配一個(gè)新的線程 給t線程//是隨機(jī)分配的,沒有規(guī)律//run不需要手動(dòng)調(diào)用,系統(tǒng)程序啟動(dòng)之后會(huì)自動(dòng)調(diào)用方法//thread.run();//這是普通方法的調(diào)用,這樣做程序只有一個(gè)線程,run方法結(jié)束之后,下邊的程序才會(huì)執(zhí)行for (int i = 0; i < 5; i++) {System.out.println("main"+i);}//有了多線程之后,main方法結(jié)束只是主線程中沒有方法棧幀了 但是其他線程或者其他棧中還有棧幀 main方法結(jié)束,程序可能還在運(yùn)行 } }class Student extends Thread {//重寫Run方法public void run() {for (int i = 0; i < 10; i++) {System.out.println("Run:"+i);}} }

四、java語言中實(shí)現(xiàn)多線程第二種方式

1.寫一個(gè)類實(shí)現(xiàn)

2.重寫run方法

?

package com.steven.demo;import java.lang.Runnable; import java.lang.Thread; public class ThreadTest02 {public static void main(String[] args) {//創(chuàng)建線程:Thread thread = new Thread(new Teacher());//啟動(dòng)線程 thread.start();} } class Teacher implements Runnable {//重寫Run方法public void run() {for (int i = 0; i < 10; i++) {System.out.println("Run:"+i);}} }

五、掌握線程方法

1.獲取當(dāng)前線程的對(duì)象 Thread.currentThread()

2.給線程起名t.setName()

3.獲取線程的名字:t.getName()

?

package com.steven.demo; public class ThreadTest03 {public static void main(String[] args) {//獲取當(dāng)前線程的對(duì)象 main主線程Thread thread = Thread.currentThread();//獲取當(dāng)前線程的名字System.out.println("當(dāng)前名稱的名稱"+thread.getName());//當(dāng)前名稱的名稱main Thread t1 = new Thread(new ArrayTest());//給線程起名t1.setName("Steven");t1.start();//線程的名稱Steven Thread thread2 = new Thread(new ArrayTest());//給線程重命名thread2.setName("珂珂");thread2.start();//線程的名稱珂珂 } } class ArrayTest implements Runnable {public void run() {Thread thread = Thread.currentThread();//獲取當(dāng)前線程的對(duì)象System.out.println("線程的名稱"+thread.getName());} }

六、線程的優(yōu)先級(jí)

優(yōu)先級(jí)高的獲取CPU時(shí)間片,相對(duì)多一些

最高:10

最小:1

默認(rèn):5

優(yōu)先級(jí)1-10

優(yōu)先級(jí)高的線程,會(huì)得到CPU的時(shí)間多一些,優(yōu)先執(zhí)行完成

?

public class ThreadTest04 {public static void main(String[] args) {System.out.println("最高"+Thread.MAX_PRIORITY);System.out.println("最小"+Thread.MIN_PRIORITY);System.out.println("默認(rèn)"+Thread.NORM_PRIORITY);Thread t1 = new Thread(new KeKe());t1.setName("t1");Thread t2 = new Thread(new KeKe());t2.setName("t2");//獲取線程的優(yōu)先級(jí)System.out.println("t1優(yōu)先級(jí)"+t1.getPriority());System.out.println("t2優(yōu)先級(jí)"+t2.getPriority());//設(shè)置優(yōu)先級(jí)t1.setPriority(5);t2.setPriority(6);//啟動(dòng) t1.start();t2.start();//線程雖然有優(yōu)先級(jí),但是隨機(jī)分配的,打印結(jié)果不一致 } } class KeKe extends Thread {public void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}} }

七、線程休眠

①Thread.sleep()使當(dāng)前正在執(zhí)行的線程執(zhí)行休眠操作(暫停執(zhí)行) 單位:毫秒

sleep 靜態(tài)方法 作用: 阻塞當(dāng)前線程,騰出CPU,讓給其他線程

public class ThreadTest05 {public static void main(String[] args) {Thread thread = new Array1();thread.setName("thread1");thread.start();//獲取當(dāng)前線程的對(duì)象 main主線程Thread t = Thread.currentThread();//獲取當(dāng)前線程的名字System.out.println("當(dāng)前名稱的名稱"+t.getName());//當(dāng)前名稱的名稱main //阻塞主線程for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "-------------------:" + i);try {Thread.sleep(2000);//程序休眠2秒鐘} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}} } class Array1 extends Thread {public void run() {System.out.println("線程正在啟動(dòng)=-====");for (int i = 0 ; i < 5 ; i ++) {System.out.println(Thread.currentThread().getName() + "-------------------:" + i);try {Thread.sleep(2000);//程序休眠2秒鐘} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}} }

②Thread.yield()暫停當(dāng)前正在執(zhí)行的線程對(duì)象,并執(zhí)行其他線程。

?1.靜態(tài)方法

?2.作用:給同一個(gè)優(yōu)先級(jí)的線程讓位,但是讓位時(shí)間不固定

?3.和sleep方法相同,就是yield的時(shí)間不固定

?他與sleep類似,只是不能由用戶執(zhí)行暫停時(shí)間,并且yield()只能讓同優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)

?

package com.steven.demo; public class ThreadTest07 {public static void main(String[] args) {//1.創(chuàng)建線程Thread thread = new HThread();thread.setName("線程07");//2.啟動(dòng)線程 thread.start();//3.主線程for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() +"---------:"+i);}System.out.println("Steven=====");} } class HThread extends Thread {public void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() +"---------:"+i);if (i % 2 == 0) {//暫定當(dāng)前線程,執(zhí)行其他線程 Thread.yield();}}} }

③線程的基本操作

/*線程的基本操作:創(chuàng)建,啟動(dòng),休眠,異常處理*/ public class ThreadTest06 {public static void main(String[] args) {try {//1.創(chuàng)建線程Thread thread = new MyThread();thread.setName("線程");//2.啟動(dòng)線程 thread.start();//3.休眠Thread.sleep(2000);System.out.println("Steven=====");}catch (InterruptedException e) {e.printStackTrace();} } }class MyThread extends Thread {public void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(3000);} catch (Exception e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() +"---------:"+i);}} }

八、線程的合并(join)

public class ThreadTest08 {public static void main(String[] args) {try {//1.創(chuàng)建線程Thread thread = new KThread();thread.setName("線程07");//2.啟動(dòng)線程 thread.start();//3.合并線程 (線程07和main線程合并)thread.join();//輸出只保證一個(gè)線程正在執(zhí)行,依次執(zhí)行,單線程的程序 (先執(zhí)行線程07后執(zhí)行main)//主線程for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() +"---------:"+i);} //當(dāng)前線程可以調(diào)用第一個(gè)線程的join方法,調(diào)用后當(dāng)前線程會(huì)被阻塞不再執(zhí)行,直到被調(diào)用的線程執(zhí)行完畢,當(dāng)前線程才會(huì)執(zhí)行} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}} } class KThread extends Thread {public void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(2000);System.out.println(Thread.currentThread().getName() +"---------:"+i);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();};}} }

九、線程同步案例

<1>模擬取款:(不使用同步機(jī)制)多線程同時(shí)對(duì)同一個(gè)賬號(hào)進(jìn)行取款操作

?

/* 模擬取款:不使用同步機(jī)制,多線程同時(shí)對(duì)同一個(gè)賬號(hào)進(jìn)行取款操作 thread 和 thread2 異步編程模型:thread線程執(zhí)行的是thread , thread2線程執(zhí)行的是thread2 ,兩個(gè)線程之間誰也不等于誰 同步編程模型:thread線程和thread2線程執(zhí)行,當(dāng)thread線程必須等thread2的線程的執(zhí)行結(jié)果之后,thread線程才能執(zhí)行 ,這是同步編程什么時(shí)候需要引入同步: 1.為了數(shù)據(jù)安全,盡管程序的使用率低,但是為了保證數(shù)據(jù)安全性,必須得加入線程同步機(jī)制, 線程同步機(jī)制 使程序變成了單線程(一個(gè)線程) 2.在什么條件下需要使用線程同步 <1>必須是多線程環(huán)境 <2>多線程環(huán)境在共享同一個(gè)數(shù)據(jù)時(shí) <3>共享的數(shù)據(jù)涉及到修改操作*/ package com.steven.demo;public class ThreadTest09 {public static void main(String[] args) {//創(chuàng)建一個(gè)公共的賬戶Account account = new Account("steven_kou",10000.0);//創(chuàng)建線程對(duì)同一個(gè)賬戶進(jìn)行取款Thread thread = new Thread(new Money(account));thread.setName("steven");Thread thread2 = new Thread(new Money(account));thread2.setName("kou");thread.start();thread2.start();} }//取款線程 class Money implements Runnable {//賬戶 Account account;Money (Account account){this.account = account;}public void run() {account.withDraw(2000.0);System.out.println("取款2000.0$,余額為:"+account.getBalance());//取款2000.0$,余額為:8000.0 (輸出兩次) }}//銀行賬戶 class Account {private String actno;private double balance;//賬戶余額public Account() {}public Account(String actno,double balance) {this.actno = actno;//成員變量|局部變量this.balance = balance;}public void setActno(String actno) {this.actno = actno;}public String getActno() {return actno;}public void setBalance(double balance) {this.balance = balance;}public double getBalance() {return balance;}//對(duì)外提供一個(gè)取款方法public void withDraw(double money) {//對(duì)賬戶進(jìn)行取款操作double after = balance - money;//延遲操作try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();//InterruptedException 線程中斷下拋出的異常 }this.setBalance(after);//更新賬戶余額,重新賦值 } }

<2>模擬取款(同步機(jī)制,同步鎖synchronized

①以下程序使用線程同步機(jī)制保證數(shù)據(jù)安全

?

package com.steven.demo; public class ThreadTest09 {public static void main(String[] args) {//創(chuàng)建一個(gè)公共的賬戶Account account = new Account("steven_kou",10000.0);//創(chuàng)建線程對(duì)同一個(gè)賬戶進(jìn)行取款Thread thread = new Thread(new Money(account));thread.setName("steven");Thread thread2 = new Thread(new Money(account));thread2.setName("kou");thread.start();thread2.start();} }//取款線程 class Money implements Runnable {//賬戶 Account account;Money (Account account){this.account = account;}public void run() {account.withDraw(2000.0);System.out.println("取款2000.0$,余額為:"+account.getBalance());//取款2000.0$,余額為:8000.0 (輸出兩次) }}//銀行賬戶 class Account {private String actno;private double balance;//賬戶余額public Account() {}public Account(String actno,double balance) {this.actno = actno;//成員變量|局部變量this.balance = balance;}public void setActno(String actno) {this.actno = actno;}public String getActno() {return actno;}public void setBalance(double balance) {this.balance = balance;}public double getBalance() {return balance;}//對(duì)外提供一個(gè)取款方法//TODO 取款 同步public void withDraw(double money) {/*需要把同步的代碼,放到同步的語句塊中thread線程執(zhí)行到此處,遇到了synchronized 關(guān)鍵字,就會(huì)去找this的對(duì)象鎖 如果找到了this的對(duì)象鎖,則進(jìn)入同步語句塊 執(zhí)行程序當(dāng)同步語句塊代碼執(zhí)行結(jié)束的時(shí)候,thread線程歸還this的對(duì)象鎖在thread線程執(zhí)行同步語句塊的過程中,如果thread2線程也執(zhí)行以下代碼。遇到synchronized 關(guān)鍵字,所以去找this對(duì)象鎖,但是該對(duì)象被thread線程持有, 只能等待thread線程使用完以后再解鎖this對(duì)象鎖*///同步鎖synchronized (this) {//對(duì)賬戶進(jìn)行取款操作double after = balance - money;//延遲操作try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();//InterruptedException 線程中斷下拋出的異常 }//更新賬戶余額,重新賦值this.setBalance(after);}} }

②synchronized關(guān)鍵字 添加到成員方法上,線程拿走的也是this對(duì)象鎖

//對(duì)外提供一個(gè)取款方法//TODO 取款 同步//synchronized關(guān)鍵字 添加到成員方法上,線程拿走的也是this對(duì)象鎖public synchronized void withDraw(double money) {/*需要把同步的代碼,放到同步的語句塊中thread線程執(zhí)行到此處,遇到了synchronized 關(guān)鍵字,就會(huì)去找this的對(duì)象鎖 如果找到了this的對(duì)象鎖,則進(jìn)入同步語句塊 執(zhí)行程序當(dāng)同步語句塊代碼執(zhí)行結(jié)束的時(shí)候,thread線程歸還this的對(duì)象鎖在thread線程執(zhí)行同步語句塊的過程中,如果thread2線程也執(zhí)行以下代碼。遇到synchronized 關(guān)鍵字,所以去找this對(duì)象鎖,但是該對(duì)象被thread線程持有, 只能等待thread線程使用完以后再解鎖this對(duì)象鎖*///同步鎖 // synchronized (this) {//對(duì)賬戶進(jìn)行取款操作double after = balance - money;//延遲操作try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();//InterruptedException 線程中斷下拋出的異常 }//更新賬戶余額,重新賦值this.setBalance(after); // }}

?

三、守護(hù)線程

①定義一個(gè)用戶線程

package com.steven.demo;//定義一個(gè)用戶線程 public class UserThread01 {public static void main(String[] args) {Runnable runnable = new UserTest();Thread thread = new Thread(runnable, "UserThread");thread.start();for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "==== " + i);}System.out.println("主線程結(jié)束---");} }class UserTest implements Runnable {public void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "==== " + i);}} }

?

②改為守護(hù)線程

package com.steven.demo; //守護(hù)線程 //其他所有的用戶線程結(jié)束,則守護(hù)線程退出 //守護(hù)線程一般都是無限執(zhí)行的 守護(hù)線程最后結(jié)束(先執(zhí)行用戶線程) //設(shè)置守護(hù)線程以后,當(dāng)前主線程結(jié)束后,守護(hù)線程并沒有把所有的數(shù)據(jù)輸出就結(jié)束 也就是說 守護(hù)線程是為用戶線程服務(wù)的,當(dāng)用戶線程全部結(jié)束,守護(hù)線程會(huì)自動(dòng)化結(jié)束public class UserThread02 {public static void main(String[] args) {Thread thread = new UserTest02();thread.setName("thread");//將thread這個(gè)用戶線程 修改為守護(hù)線程thread.setDaemon(true);thread.start();//主線程 for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "==== " + i);try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}System.out.println("主線程結(jié)束---");} } class UserTest02 extends Thread {public void run() {int i = 0;while (true) {i ++;System.out.println(Thread.currentThread().getName() +"====:"+i);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}} }

四、定時(shí)器簡單使用:

?

package com.steven.demo;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; import java.util.TimerTask;/*Timer 定時(shí)器*/ public class TimerTest01 {public static void main(String[] args) {System.out.println("來了"); Timer timer = new Timer();try {Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2018-10-07 19:26:02");//安排在指定的時(shí)間執(zhí)行指定的任務(wù)timer.schedule(new MyTimer(), date,1000*60*60*24);//date執(zhí)行后續(xù)任務(wù)的時(shí)間間隔 設(shè)置定時(shí)任務(wù):在2018-10-07 19:26:02執(zhí)行此任務(wù), 24小時(shí)執(zhí)行一次//timer.schedule(new MyTimer(), date,1000*2);//如果設(shè)置每天執(zhí)行一次:Date date = new SimpleDateFormat("HH:mm:ss").parse("19:26:02"); }catch (ParseException e) {e.printStackTrace();} catch (NullPointerException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalStateException e) {e.printStackTrace();}} }class MyTimer extends TimerTask {public void run() {System.out.println("=="+new Date());//==Sun Oct 07 19:26:02 CST 2018 }}

?

?

?

?

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/StevenHuSir/p/Java_Thread.html

總結(jié)

以上是生活随笔為你收集整理的java-多线程操作全(Thread)-Timer简单使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。