在java中要想實(shí)現(xiàn)多線程,有兩種手段,一種是繼續(xù)Thread類(lèi),另外一種是實(shí)現(xiàn)Runable接口。那么:為什么我們不能直接調(diào)用run()方法呢? 我的理解是:線程的運(yùn)行需要本地操作系統(tǒng)的支持。 如果你查看start的源代碼的時(shí)候,會(huì)發(fā)現(xiàn):
注意我用紅色加粗的那一條語(yǔ)句,說(shuō)明此處調(diào)用的是start0()。并且這個(gè)這個(gè)方法用了native關(guān)鍵字,次關(guān)鍵字表示調(diào)用本地操作系統(tǒng)的函數(shù)。因?yàn)槎嗑€程的實(shí)現(xiàn)需要本地操作系統(tǒng)的支持。
class hello extends Thread {
public hello() {
}
public hello(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "運(yùn)行 " + i);
}
}
public static void main(String[] args) {
hello h1=new hello("A");
hello h2=new hello("B");
h1.start();
h2.start();
}
private String name;
}
class hello implements Runnable {
public hello() {
}
public hello(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "運(yùn)行 " + i);
}
}
public static void main(String[] args) {
hello h1=new hello("線程A");
Thread demo= new Thread(h1);
hello h2=new hello("線程B");
Thread demo1=new Thread(h2);
demo.start();
demo1.start();
}
private String name;
}
Thread和Runnable的區(qū)別:
如果一個(gè)類(lèi)繼承Thread,則不適合資源共享。但是如果實(shí)現(xiàn)了Runable接口的話,則很容易的實(shí)現(xiàn)資源共享。
class MyThread implements Runnable{
private int ticket = 5; //5張票
public void run() {
for (int i=0; i<=20; i++) {
if (this.ticket > 0) {
System.out.println(Thread.currentThread().getName()+ "正在賣(mài)票"+this.ticket--);
}
}
}
}
public class lzwCode {
public static void main(String [] args) {
MyThread my = new MyThread();
new Thread(my, "1號(hào)窗口").start();
new Thread(my, "2號(hào)窗口").start();
new Thread(my, "3號(hào)窗口").start();
}
}
class hello implements Runnable {
public void run() {
for(int i=0;i<10;++i){
synchronized (this) {
if(count>0){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(count--);
}
}
}
}
public static void main(String[] args) {
hello he=new hello();
Thread h1=new Thread(he);
Thread h2=new Thread(he);
Thread h3=new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count=5;
}
也可以采用同步方法。
語(yǔ)法格式為synchronized 方法返回類(lèi)型方法名(參數(shù)列表){
// 其他代碼
}
class hello implements Runnable {
public void run() {
for (int i = 0; i < 10; ++i) {
sale();
}
}
public synchronized void sale() {
if (count > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count--);
}
}
public static void main(String[] args) {
hello he = new hello();
Thread h1 = new Thread(he);
Thread h2 = new Thread(he);
Thread h3 = new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count = 5;
}
總結(jié)一下吧:
實(shí)現(xiàn)Runnable接口比繼承Thread類(lèi)所具有的優(yōu)勢(shì):
1):適合多個(gè)相同的程序代碼的線程去處理同一個(gè)資源
2):可以避免java中的單繼承的限制
3):增加程序的健壯性,代碼可以被多個(gè)線程共享,代碼和數(shù)據(jù)獨(dú)立。
【使用線程同步解決問(wèn)題】
采用同步的話,可以使用同步代碼塊和同步方法兩種來(lái)完成。
更多信息請(qǐng)查看IT技術(shù)專(zhuān)欄