Java定义了两种创建线程的方法:
1.实现Runnable接口
要实现Runnable接口,只需简单地实现run()方法即可,声明如下:public void run()
在run()方法中,可以定义构成新线程的代码。需重点理解的是,run()可以调用其它方法、使用其他类和声明变量,就像主线程能做的那样。唯一的区别是:run()方法是程序的另一个并发的执行线程的进入店,这个线程在run()方法返回时结束。
创建新线程以后,直到调用了它的start()方法后才会执行。本质上,start()执行对run()的调用。
// Create a second thread. public class NewThread implements Runnable{ Thread t; NewThread(){ t=new Thread(this,"Demo Thread"); System.out.println("Child thread: "+t); t.start(); } // This is the entry point of the second thread. public void run(){ try{ for(int i=5;i>0;i--){ System.out.println("Child thread: "+i); Thread.sleep(500); } } catch(InterruptedException e){ System.out.println("Child thread interrupted"); } System.out.println("Exiting child thread"); } } class ThreadDemo{ public static void main(String args[]){ new NewThread(); try{ for(int i=5;i>0;i--){ System.out.println("Main thread: "+i); Thread.sleep(1000); } } catch(InterruptedException e){ System.out.println("Main thread interrupted"); } System.out.println("Exiting Main thread"); } }
输出:
Child thread: Thread[Demo Thread,5,main]
Main thread: 5
Child thread: 5
Child thread: 4
Main thread: 4
Child thread: 3
Child thread: 2
Main thread: 3
Child thread: 1
Exiting child thread
Main thread: 2
Main thread: 1
Exiting Main thread
2. 扩展Thread类本身
第二种创建线程的方法是创建一个扩展Thread类的新类,然后创建该类的一个实例。这个扩展的类必须重写run()方法,这是新线程的进入点,同时它也必须调用start()方法来执行线程。
// Create a second thread. public class NewThread extends Thread{ NewThread(){ super("Demo thread"); System.out.println("Child thread: "+this); start(); } // This is the entry point of the second thread. public void run(){ try{ for(int i=5;i>0;i--){ System.out.println("Child thread: "+i); Thread.sleep(500); } } catch(InterruptedException e){ System.out.println("Child thread interrupted"); } System.out.println("Exiting child thread"); } } class ThreadDemo{ public static void main(String args[]){ new NewThread(); try{ for(int i=5;i>0;i--){ System.out.println("Main thread: "+i); Thread.sleep(1000); } } catch(InterruptedException e){ System.out.println("Main thread interrupted"); } System.out.println("Exiting Main thread"); } }
输出:
Child thread: Thread[Demo thread,5,main]
Main thread: 5
Child thread: 5
Child thread: 4
Main thread: 4
Child thread: 3
Child thread: 2
Main thread: 3
Child thread: 1
Exiting child thread
Main thread: 2
Main thread: 1
Exiting Main thread
同步:当两个或多个线程需要访问同一共享资源时,需要某种方式来确保资源在某一时刻只被一个线程使用,这个方式称为同步。
不使用同步的例子:
class Callme{ void call(String msg){ System.out.print("["+msg); try{ Thread.sleep(1000); } catch(InterruptedException e){ System.out.println("Interrupted"); } System.out.println("]"); } } class Caller implements Runnable{ String msg; Callme target; Thread t; public Caller(Callme targ, String s){ target=targ; msg=s; t=new Thread(this); t.start(); } public void run(){ target.call(msg); } } public class Synch { public static void main(String args[]){ Callme target=new Callme(); Caller ob1=new Caller(target,"Hello"); Caller ob2=new Caller(target,"Synchronized"); Caller ob3=new Caller(target,"World"); try{ ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch(InterruptedException e){ System.out.println("Interrupted"); } } }
输出:
[Hello[World[Synchronized]
]
]
使用同步,只需简单地在call()的定义前面加上关键字synchronized即可
class Callme{ synchronized void call(String msg){
输出:
[Hello]
[Synchronized]
[World]
当不能在类相应的方法中添加synchronized关键字时,只需要将对该类方法的访问置于一个synchronized快中
public void run(){ synchronized(target){ target.call(msg); } }