java多线程论文_Java5 多线程之入门篇-论文
Java5?多線程之入門篇
Java5 多線程之入門篇
首先回顧一下JDK1.5之前的線程相關(guān)的知識:
1 線程的入門.
什么是線程,線程就是程序執(zhí)行的線索,Java是面向?qū)ο蟮恼Z言什么類來表示這樣一個(gè)東西呢?Thread.
通過start()方法啟動它,線程所要執(zhí)行的任務(wù)放在run()方法里面,下面可以看一下run()方法里面的源碼
創(chuàng)建線程的兩種傳統(tǒng)方式(注: Runnable類并不是一個(gè)線程,它只是線程一個(gè)執(zhí)行單元):
打開Thread的構(gòu)造方法,
然后可以跟進(jìn)看到init()方法具體的實(shí)現(xiàn).其中有一行代碼就是對target(Runnable類型)的賦值,因?yàn)榫€程所執(zhí)行的任務(wù)都在run()方法里面,那么在run()方法里面,target就不為null,然后就調(diào)用了Runnale的run()方法.因?yàn)槲覀冎貙懥薘unnable的run()方法,那么最終執(zhí)行的就是我們所覆寫的run()方法.具體代碼如下:
如果我們同時(shí)實(shí)現(xiàn)了Thread的run()方法又同時(shí)覆蓋了Runnable的run()方法.那么到底會執(zhí)行哪個(gè)的run()方法呢?
根據(jù)Java的多態(tài),肯定執(zhí)行的是Thread的run()方法.因?yàn)槲覀兏矊懥薚hread的run()方法,那么所執(zhí)行的就是我們r(jià)un()方法,而不是
2 傳統(tǒng)的定時(shí)器:
定時(shí)器通過Timer這個(gè)類來描述,通過schedule()方法來調(diào)度,定時(shí)執(zhí)行的任務(wù)通過TimerTask來定義.
下面來實(shí)現(xiàn)一個(gè)簡單的定時(shí)器,功能如下,每隔2秒執(zhí)行一次,之后隔4秒執(zhí)行一次,然后又隔2秒,就這樣輪循下去.具體用法可以查看API里面有詳細(xì)介紹.
[java] view plaincopy 01.public static void main(String[] args) {
02.??? new Timer().schedule(new MyTimerTask(), 2000);
03.??? try {
04.??????? while (true) {
05.??????? System.out.println(new Date().getSeconds());
06.??????? Thread.sleep(1000);
07.??? }
08.} catch (InterruptedException e) {
09.??? e.printStackTrace();
10.??????? }
11.??? }
12.??? }
13.class MyTimerTask extends TimerTask {
14.??? static int count = 0;
15.??? @Override
16.??? public void run() {
17.??????? count = (count + 1) % 2;//count=0或1
18.??????? System.out.println("boming");
19.??????? Timer timer = new Timer();
20.??????? timer.schedule(new MyTimerTask(), 2000 + (2000) * count);
21.??? }
3 線程之間的互斥和同步通信
當(dāng)兩個(gè)線程去同時(shí)操作一個(gè)字符串,那么可能會出現(xiàn)線程安全問題.這樣的情況可以用銀行轉(zhuǎn)帳來解釋.
下面的代碼就會出現(xiàn)問題,
[java] view plaincopy 01.public static void main(String[] args) {
02.final Outputer outputer = new Outputer();
03.new Thread() {
04.@Override
05.public void run() {
06.while (true) {
07.try {
08.Thread.sleep(100);
09.} catch (InterruptedException e) {
10.e.printStackTrace();
11.}
12.outputer.print("zhangsan");
13.}
14.}
15.}.start();
16.new Thread() {
17.@Override
18.public void run() {
19.while (true) {
20.try {
21.Thread.sleep(100);
22.} catch (InterruptedException e) {
23.e.printStackTrace();
24.}
25.outputer.print("zhangxiaoxiang");
26.}
27.}
28.}.start();
29.}
30.}
31.class Outputer {
32.public void print(String name) {
33.for (int i = 0; i < name.length(); i++) {
34.System.out.print(name.charAt(i));
35.}
36.System.out.println();// 打印完字符串換行
37.}
38.}
我們使用兩個(gè)線程去調(diào)用print(String name)方法,當(dāng)?shù)谝粋€(gè)方法還沒有執(zhí)行完畢,第二個(gè)方法來執(zhí)行,那么打印出來的name就會出現(xiàn)為問題.如下圖所示,
現(xiàn)在我們要實(shí)現(xiàn)的是,只有當(dāng)?shù)谝粋€(gè)線程執(zhí)行完畢后,第二個(gè)線程才能執(zhí)行print(String name)方法,這就必須互斥或者說同步.
我們知道實(shí)現(xiàn)同步可以使用同步代碼塊或者同步方法,想到同步(Synchronized)那么自然而然就想到同步監(jiān)視器.
這是兩個(gè)很重要的概念.
現(xiàn)在我們來改造上面Outputer的print(String name)方法.
[java] view plaincopy 01.public void print(String name) {
02.//synchronized()里面的參數(shù)就是同步監(jiān)視器
03.//然而這里使用name作為同步監(jiān)視器是不行的,
04.//因?yàn)橐獙?shí)現(xiàn)原子性(互斥)必須要使用同一個(gè)監(jiān)視器對象
05.//當(dāng)?shù)谝粋€(gè)線程來執(zhí)行該代碼塊,name對象是一個(gè)String對象
06.//當(dāng)?shù)诙€(gè)線程來執(zhí)行,name對象又是另一個(gè)String對象,
07.//這樣就不能實(shí)現(xiàn)同步
08.synchronized (name) {
09.for (int i = 0; i < name.length(); i++) {
10.System.out.print(name.charAt(i));
11.}
12.System.out.println();// 打印完字符串換行
13.}
14.}
執(zhí)行結(jié)果如下所示:
我們可以通過this關(guān)鍵字作為同步監(jiān)視器,因?yàn)閺纳厦娑x兩個(gè)線程的代碼來看,我們只new了一次Outputer對象,所以this代表同一個(gè)對象.
現(xiàn)在來通過同步方法來實(shí)現(xiàn)同步,
[java] view plaincopy 01.//同步方法也同樣也有同步監(jiān)視器,它是this
02.public synchronized void print2(String name) {
03.??? for (int i = 0; i < name.length(); i++) {
04.??????? System.out.print(name.charAt(i));
05.??? }
06.??? System.out.println();// 打印完字符串換行
07.}
把第二個(gè)線程改成使用print2(String name)方法.這樣的話就需要p
總結(jié)
以上是生活随笔為你收集整理的java多线程论文_Java5 多线程之入门篇-论文的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C指针原理(4)-ATT汇编
- 下一篇: numpy(2)-非齐次线性方程组求解