天天看點

Java面向對象(二)學習筆記 補線程

前言:

封裝、繼承、多态之後抽象以及接口的學習需要特别重視!!!

補:

String 方法是在堆之中

面向對象思想:

抽象類,沒有業務意義,比如寵物吃東西, 我們借用abstract 設計抽象類,此時編譯器會進行提示

Note:

構造函數不能抽象,抽象類中可以有抽象方法供子類調用

接口:

JAVA借用接口實作多繼承,這一點與C++非常不一樣。側重點在行為

學習樣例:

開發列印機---面向接口程式設計

需求:

墨盒;彩色,黑白

紙張:A4,B5

黑盒和紙張都不是列印機廠商提供的,列印機廠商要相容市場上的墨盒、紙張

墨盒接口:得到顔色,  

實作接口:1.彩色  2.黑白

紙張接口 :得到紙張

紙張類型:1.A4  2.B5

行為是列印:

輸出:使用黑白墨盒在A4紙張上列印。

部分代碼如下

接口

package com.ydl.ch04;

public interface Paper {
	
	public String getSize() ;
}
           

 實作接口

package com.ydl.ch04;

public class A4Paper implements Paper {
	String paper="A4紙張";
	@Override
	public String getSize() {
		this.paper="A4紙張";
		//System.out.println("使用"+paper);
		return paper;
	}

}
           

列印機類 

package com.ydl.ch04;

public class NewPrinter {
	public Paper paper;
	public Printer pri;
	public Paper getPaper() {
		return paper;
	}
	public void setPaper(Paper paper) {
		this.paper = paper;
	}
	public Printer getPri() {
		return pri;
	}
	public void setPri(Printer pri) {
		this.pri = pri;
	}
	public void display(){
		System.out.println("使用"+paper.getSize()+"進行"+pri.getInk()+"列印");
	}
	
}
           

測試類:

package com.ydl.ch04;

public class Test {
	public static void main(String[] args) {
		/*Paper pa1=new A4Paper();
		Printer pr1=new ColorPrint();
		System.out.println(pa1.getSize()+pr1.getInk());
		Paper pa2=new B5Paper();
		Printer pr2=new InkPrint();
		System.out.println(pa2.getSize()+pr2.getInk());*/
		A4Paper a4=new A4Paper();
		ColorPrint c4=new ColorPrint();
		NewPrinter n4=new NewPrinter();
		n4.setPaper(a4);
		n4.setPri(c4);
		n4.display();
		B5Paper b5=new B5Paper();
		InkPrint c5=new InkPrint();
		NewPrinter n5=new NewPrinter();
		
		n5.setPaper(b5);
		n5.setPri(c5);
		n5.display();
		
		n5.setPaper(a4);
		n5.setPri(c5);
		n5.display();
		
		n5.setPaper(b5);
		n5.setPri(c4);
		n5.display();
	}
}
           

Notes:

與C++不同,JAVA不用直接的多繼承,而采用接口,實作多繼承

靜态:

靜态方法的調用:盡量使用類名來調用,免得與普通方法弄混,當然JAVA編譯器會幫我們進行優化

靜态代碼塊:

不需要調用就會加載

下面附上小馬哥筆記

Java面向對象(二)學習筆記 補線程

 static成員在JVM中的存儲

Java面向對象(二)學習筆記 補線程

如何了解接口是一種能力

  1. 可以被多繼承
  2. 設計和實作完全分離
  3. 更自然的使用多态
  4. 更容易搭建程式架構
  5. 更容易更換實作:比如插座,提供充電的功能,比如市場上所有插座的都是2-3個插口
Java面向對象(二)學習筆記 補線程

線程學習:

實際開發用得少,面試卻比較多

線程的實作有兩種方式:

  • extends Thread 繼承來實作
  • implememnts Runable 借助接口來實作

線程優先級:1--10

線程的排程:

1.static void sleep(毫秒);

2void join();強制執行

3.static void yield()禮讓

4.void interupt()

通過幾個案例進行學習:

同步鎖以及Runable接口實作:黃牛搶票、1000接力賽

線程強制、禮讓:醫院叫号:

線程休眠:多人爬山:

   具體需求可以操作網上其他網站;

主要目的:

同步鎖、Runable接口實作方式的資源共享的學習:

黃牛搶票、1000接力賽其實是同個問題

package com.projo;

public class Site implements Runnable{
	int total=10;//剩餘票數
	int currNumber=0;//目前票數
	boolean result=true;
	
	@Override
	public void run() {
		while(total>0){
			//System.out.println(Thread.currentThread().getName());
			synchronized (this) {
				if (total<=0) {
					break;
				}
				try {
				Thread.sleep(500);
				total--;
				currNumber++;
				System.out.println(Thread.currentThread().getName()+
						"搶到第"+currNumber+"還剩"+total+"張票");
				} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				}
			}
			
		}
	}

}
           

測試主函數入口:

package com.projo;

public class TestSite {
	public static void main(String[] args) {
		Site s=new Site();
		
		Thread p1=new Thread(s,"黃牛");
		p1.setPriority(8);
		Thread p2=new Thread(s,"學生");
		Thread p3=new Thread(s,"老師");
		
		p1.start();
		p2.start();
		p3.start();
		
	}
}
           

線程強制與禮讓問題:

 醫院叫号:

package com.projo;

public class TestCallThread {

	public static void main(String[] args) {
		CallThread call=new CallThread();
		Thread c1=new Thread(call,"特殊号:");
		c1.start();
		for (int i = 1; i <= 50; i++) {
			if (i==10) {
				try {
					c1.join();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			try {
				c1.sleep(100);
				c1.currentThread().setName("普通号:");
				System.out.println(c1.currentThread().getName()+"第"+i+"個病人再看病!");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}
           

最後貼上多線程模拟接力賽跑步:

package com.runprojo;

public class Relay implements Runnable {
	
	private int num=10;//每人跑10m
	private int total=1000;//總共1000
	
	@Override
	public void run() {
		while(total>=0){
			synchronized (this) {
				System.out.println(Thread.currentThread().getName()+"拿到接力棒");
				if (total==0) {
					System.out.println("比賽結束");
					break;
				}
				total-=100;
				try {
					for (int i = 1; i <=num; i++) {
						System.out.println(Thread.currentThread().getName()+"跑了"+i*10+"m");
						Thread.sleep(500);
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}
           

 測試入口:

package com.runprojo;

public class TestRelay {

	public static void main(String[] args) {
		Relay run=new Relay();
		Thread runner1=new Thread(run,"1号選手");
		Thread runner2=new Thread(run,"2号選手");
		Thread runner3=new Thread(run,"3号選手");
		Thread runner4=new Thread(run,"4号選手");
		Thread runner5=new Thread(run,"5号選手");
		Thread runner6=new Thread(run,"6号選手");
		Thread runner7=new Thread(run,"7号選手");
		Thread runner8=new Thread(run,"8号選手");
		Thread runner9=new Thread(run,"9号選手");
		Thread runner10=new Thread(run,"10号選手");
		Thread runner11=new Thread(run,"11号選手");
		runner1.start();
		runner2.start();
		runner3.start();
		runner4.start();
		runner5.start();
		runner6.start();
		runner7.start();
		runner8.start();
		runner9.start();
		runner10.start();
		runner11.start();
		
		
		
	}

}
           

繼續閱讀