java 多線程

最近工做上有個地方須要用到多線程,是用C++的,下午加班改代碼,可是網絡出現問題,連不了主機,因而在java上面測試並回顧了一些知識。記錄一下。java

1.多線程的類helloworld。網絡

在thread類中持有一個實現了runnable接口的實例化對象,而後thread類run的時候,會調用runnable的run。這一點在不少入門的書籍中都有介紹,不必贅述,可是爲何要這麼寫,這裏稍微把java中的代碼粘貼一下。代碼以下:多線程

Thread類有一個接受runnable實現對象的構造函數,ide

public Thread(Runnable target) {
	init(null, target, "Thread-" + nextThreadNum(), 0);
    }

  init函數中最重要的一段代碼是:this.target = target;函數

即給Thread的target這個變量set成了傳進來的target。當Thread的run執行的時候,實際上會調用target的run函數。在源碼中是這麼說的「/**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.」oop

也就是Thread的start執行之後調用Thread的run方法。而run方法會調用target的run方法,代碼以下:測試

public void run() {
	if (target != null) {
	    target.run();
	}
    }

  測試的Thread主類以下:this

public class TestThread {
    
    static int threadNum = 10;
    static int maxloop = 10000; 
    
	public static void main(String arg[])
    {
        Thread threads[] = new Thread[100];

		for( int i = 0; i <= threadNum ; ++i)
        {
        	String threadName = "Thread " + Integer.valueOf(i);
        	threads[i] = new Thread(new TestRunable(threadName,maxloop));
        	threads[i].start();
        }
		
		for( int i = 0; i <= threadNum ; ++i)
        {
			try {
				threads[i].join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			System.out.println(Integer.valueOf(i) + "thread done.");
			
        }
		System.out.println( "count==" + Integer.valueOf( Global.count ) );
		
    }
}

  這裏用到了一個全局變量Global.count,其目的在下面第三點說明。線程

2.測試join函數。join函數就是等待自身的函數,其效果以下:code

8thread done.

。。。

Thread 9  9999
Thread 9  10000
9thread done.
10thread done.

也就是在線程8結束之後,線程9還未結束,那麼主線程就一直等待線程9結束之後,再等待線程10結束,而後再繼續往下執行。

3.測試線程操做統一個未上鎖的變量的狀況。

這裏先把實現了runnable接口的類也貼出來。

package test;

public class TestRunable implements Runnable {
    
	private
		int mi;
	    String ms;
	    int mmaxloop;
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		
		for( int i = 0;i<=mmaxloop*10;++i  )
		{
		    System.out.println( ms + "  " + Integer.valueOf(mi));
		    ++mi;
		    ++Global.count;
		}
	}
    
	TestRunable(String ss,int maxLoop)
	{
		this.mi = 0;	
		this.ms = ss;
		mmaxloop = maxLoop;
	}
}

  此外,還有全局變量的類也一道貼出來:

public class Global {
	public
    static int count = 0;
}

  其結果是每次測試的結果,對全局變量的打印數字都不一致。

好比,某次執行的結果是(對源碼中的某些數字可能進行一些放大或者縮小,不影響其效果): 

7thread done.
8thread done.
9thread done.
10thread done.
count==1100010

另一次執行的結果是:

7thread done.
8thread done.
9thread done.
10thread done.
count==1100011

4.互斥實現。

 testRunnable類的代碼修改成:

for( int i = 0;i<=mmaxloop*100;++i  )
		{
		    System.out.println( ms + "  " + Integer.valueOf(mi));
		    ++mi;
		    synchronized(this)
		    {
		        ++Global.count;
		    }
		}

  再執行屢次,查看Global.count結果,都是一個值嗎?

第一次:

count==1100009

第二次:

8thread done.
9thread done.
10thread done.
count==1100011

因而,發現根本就沒有完成互斥。

5.原來互斥是須要針對一個對象的。通過修改之後的代碼以下,就能夠完成互斥了。

static int threadNum = 10;
    static int maxloop = 1000; 
    
	public static void main(String arg[]) {
		Thread threads[] = new Thread[100];
		System.out.println("ssssssssssss");
		Global global = new Global();
		String threadName = "same";
		TestRunnable testRunnable = new TestRunnable(threadName, maxloop,
				global);
		for (int i = 0; i <= threadNum; ++i) {
			// String threadName = "Thread " + Integer.valueOf(i);
			threads[i] = new Thread(testRunnable);
			threads[i].start();
		}

		for (int i = 0; i <= threadNum; ++i) {
			try {
				threads[i].join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// System.out.println(Integer.valueOf(i) + "thread done. mi==" +
			// Integer.valueOf(threads[i].g));

			System.out.println(Integer.valueOf(i)
					+ "thread done. global.count=="
					+ Integer.valueOf(global.count));

		}
		System.out.println("count==" + Integer.valueOf(global.count));

	}

  results:

count==1100000

執行屢次都是一個結果。

相關文章
相關標籤/搜索