【文章標題】Java線程類小結(附思維導圖)
【文章作者】曾健生
【作者郵箱】[email protected]
【作者QQ】190678908
【作者博客】http://blog.csdn.net/newjueqi
【編程環境】JDK 1.6.0_01
【作者聲明】歡迎轉載文章,但轉載請保留文章的完整性以及註明文章的出處。
*******************************************************************************
一. 多線程的意義
1. 原由:兩個或兩個以上的代碼塊需要同時運行
2. 創建方法:
a.繼承Thread類覆蓋run方法
b.實現Runnable接口中的run方法,把實現Runnable接口的子類對象傳遞給Thread類的構造函數。
下面是a和b兩種方法的代碼例子
/*
多線程實現的第一種方法,繼承Thread類
*/
/*
class TestThread extends Thread
{
public void run()
{
while(true)
{
System.out.println( "TestThread" );
}
}
}
*/
/*
多線程實現的第二種方法,實現Runnable接口
*/
class TestThread implements Runnable
{
public void run()
{
while(true)
{
System.out.println( "TestThread" );
}
}
}
class BaseThread
{
public static void main(String ars[])
{
//第一種啓動多線程的方法
//new TestThread().start();
//第二種啓動多線程的方法
new Thread( new TestThread()).start();
while(true)
{
System.out.println( "main" );
}
}
}
定義Runnable接口的好處:不需要加入Thread類的繼承體系中,如果該類已繼承了父類,但需要同時運行多塊代碼,java爲了實現這個功能,暴露了Runnable接口,只要覆蓋了其中的run方法,把需要運行的代碼寫入其中即可,避免了單繼承的侷限性。
下面的代碼例子簡單的模擬了一下Thread類的設計思想:
/*
演示了多線程兩種實現方法的實現機制
*/
interface MyRunnable
{
public void run();
}
class MyThread
{
private MyRunnable mr;
public MyThread(){}
public MyThread( MyRunnable mr )
{
this.mr=mr;
}
public void run()
{
mr.run();
}
public void start()
{
this.run();
}
}
/*
//通過繼承的方法實現多線程
class Test extends MyThread
{
public void run()
{
System.out.println( " entends run " );
}
}
*/
//通過實現接口的方法實現多線程
class Test implements MyRunnable
{
public void run()
{
System.out.println( " interface run " );
}
}
class Demo
{
public static void main( String args[])
{
//通過繼承的方法實現多線程
/* Test t=new Test();
t.start();
*/
//通過實現接口的方法實現多線程
Test t=new Test();
MyThread mt=new MyThread( t );
mt.start();
}
}
二. 線程安全問題
1. 線程的最大特點:隨機性
2. 使用同步可解決以上的問題:
a, 原理:把代碼封裝並加鎖
b, 注意兩點:
1. 兩個或兩個以上的線程使用同一資源
2. 使用同一把鎖
c, 兩種方法:
1. 使用同步代碼塊(Synchronized)
2. 使用同步函數(Synchronized)
3.要注意由於線程嵌套而出現死鎖的情況。
三.線程間的通信
1. 常用的函數
sleep(),wait(),notify(),notifyAll(),toString(),setPriority()
其中wait(),notify(),notifyAll()都是在Object類中,因爲可以被任意對象所調用的方法。一定定義在Object類中。
sleep()和wait()的區別
sleep():釋放資源,不釋放鎖
wait():、釋放資源,釋放鎖
下面是一個線程通信的例子
/*
線程的通信問題, 一個輸出必須在一個輸入完成後纔可以進行,用到了線程間通信的知識
*/
class Res
{
String name;
String sex;
boolean b=true;
public synchronized void set( String name, String sex )
{
if( b)
try{ this.wait();}catch( Exception e ){}
this.name=name;
this.sex=sex;
b=true;
notify();
}
public synchronized void out()
{
if( !b)
try{ this.wait();}catch( Exception e ){}
b=false;
notify();
System.out.println( Thread.currentThread().getName()
+"---"+name+" "+sex );
}
}
class Input implements Runnable
{
Res r;
int i=0;
Input( Res r)
{
this.r=r;
}
public void run()
{
while( true )
{
if( i==0)
{
r.set( " dsdf","nan");
}
else
{
r.set( " 麗麗","女");
}
i=(i+1)%2;
}
}
}
class Output implements Runnable
{
Res r;
Output( Res r )
{
this.r=r;
}
public void run()
{
while( true )
{
r.out();
}
}
}
class Demo1
{
public static void main( String aers[])
{
Res r=new Res();
new Thread( new Input(r)).start();
new Thread( new Output(r)).start();
}
}
2.如何結束運行的線程
以前通過stop()方法。但該方法已過時。現在可以通過定義標記的形式來控制循環。因爲線程一般都是循環做某些事情,所以可通過結束標誌的方法結束線程。
最後附上一幅這篇學習筆記的思維導圖:
(如果博客上不能完整顯示,請保存到本地後查看)