java高級部分(七)-(序列化-屬性集合類,多線程)

序列化

 序列化:將對象按照流的方式存儲到文本文件中或者再網絡中傳輸    對象---->流數據 序列化流 (ObjectOutputStream)

 反序列化:將文本文件中的流對象或者網絡傳輸中的流對象還原成對象   流數據--->對象  反序列化流(ObjectInputStream)

 java.io.NotSerializableException :當前類未實現序列化功能的異常

   Serializable:接口 沒有構造方法,沒有字段,也沒有方法

   接口---->標記接口

   自定義類要實現序列化功能,必須實現接口Serializable接口

   類實現了serializable也意味着他是標記類

    假設之前操作針對Peroson操作序列的時候,產生一個標記  Preson.class--->固定ID 100

    name -100

    age -100

    已經序列化完畢了,然後有修改了Person類裏面的一些東西,加入了toString()

    Person.class---固定id -- 200

   org.westos_01.Person; local class incompatible:

    stream classdesc serialVersionUID = -428218385429329797,

    local class serialVersionUID = -5865763454468005049

   

   因爲手動修改了這些類的屬性/成員變量,將序列化版本Id改變了

   InvalidClassException:一般情況:該類的序列版本號與從流中讀取的類描述符的版本號不匹配

   實際開發中,不想多次對當前這些序列化,如果這樣做,非常麻煩?

   如何解決呢?

    讓當前實現類序列化功能的這個類產生一個固定ID,注意看程序有黃色警告線,直接就點它固定Id

   創建一個序列化流對象

public ObjectOutputStream(OutputStream out)

                public final void writeObject(Object obj)

    創建反序列化流對象
public ObjectInputStream(InputStream in)

public final Object readObject():從 ObjectInputStream 讀取對象。

public static void main(String[] args) throws Exception {
		extracted();
		extracted2();
	}

	private static void extracted2() throws IOException, FileNotFoundException, Exception {
		ObjectInputStream ois=new ObjectInputStream(new FileInputStream("ois.txt"));
		Object object = ois.readObject();
		ois.close();
		System.out.println(object);
		
	}

	private static void extracted() throws IOException, FileNotFoundException {
		
		ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("ois.txt"));
		Student s=new Student("張三", 25);
		oos.writeObject(s);
		oos.close();
	}

 

class Student implements Serializable{
	
	private static final long serialVersionUID = 1L;

 

                      屬性集合類

 

Properties:表示了一個持久的屬性集(簡稱:屬性集合類)  extends Hashtable<K,V> Map集合的

  可保存在流中或從流中加載。屬性列表中每個鍵及其對應值都是一個字符串。

  public Properties():無參構造 

屬性集合類的特有功能:

  public Object setProperty(String key, String value) :給屬性列表中添加鍵和值,並且強制都使用String

  public Set<String> stringPropertyNames():遍歷的功能

  public String getProperty(String key)用指定的鍵在此屬性列表中搜索屬性

可保存在流中或從流中加載,只能使用屬性集合類

 public void store(Writer writer,String comments):把集合中的數據保存文本文件中(屬性集合)

 public void load(Reader reader):將文本文件中的數據加載到屬性集合中

private static void extracted2() throws Exception {
		FileReader fr=new FileReader("name.txt");
		Properties pro=new Properties();
		pro.load(fr);;
		fr.close();
		System.out.println(pro);
		
	}

 

                                          多線程

JVM:Java虛擬機 識別main(主線程)

MyThread類就是一個執行線程類

 並且重寫Thread類中的run 方法

  run()方法裏面應該是一些耗時的操作,IO操作/循環語句..

class MyThread extends Thread{
	@Override
	public void run() {
		System.out.println("helloworld");
		for(int x = 0 ;x <200; x ++) { //兩個線程都需要執行這個代碼
			System.out.println(x);
		}
	}
}

 

如何實現多線程程序呢?

 

 要實現多線程程序,需要開啓進程,

 開啓進程,是需要創建系統資源,但是Java語言不能創建系統資源

 只有C/C++可以創建系統資源, 利用c語言創建好的系統資源實現

 Java提供了一個類:Thread

  實現多線程程序的步驟:

  1)將類聲明爲 Thread 的子類

  2)該子類應重寫 Thread 類的 run 方法

  3)在主線程進行該自定義的線程類的對象的創建

public class 多線程的創建 {
	public static void main(String[] args) {
		MyThread mt=new MyThread();
		mt.start();
		MyThread mt2=new MyThread();
		mt2.start();
	}

}

 

 並行和併發(高併發:MyBatis --->IBatis:半自動化)

 強者邏輯上的同時,指的是同一個時間段內

 後者物理上的同時,指的是同一個時間點

 

Thread 類提供了一些方法

  public final void setName(String name):給線程起名稱

  public final String getName() :獲取線程名稱

Thread類中提供另一個功能:

public static Thread currentThread():返回當前正在執行的線程對象的引用

private static int threadInitNumber;  當前線程編號

        public final void setDaemon(boolean on) :true時,表示爲守護線程

      將該線程標記爲守護線程或用戶線程。當正在運行的線程都是守護線程時,Java 虛擬機退出。(守護線程不會立即結束掉,它會執行一段時間在結束掉)

  該方法必須在啓動線程前調用。

public static void main(String[] args) {
		
		//創建兩個子線程
		ThreadDaemon td1 = new ThreadDaemon() ;
		ThreadDaemon td2 = new ThreadDaemon() ;
		
		td1.setName("張飛");
		td2.setName("關羽");
		
		//在啓動之前,設置爲守護線程
		td1.setDaemon(true); 
		td2.setDaemon(true);
		
		td1.start();
		td2.start(); 
		
		Thread.currentThread().setName("劉備");
		for(int x =0 ; x < 5 ; x ++) {
			System.out.println(Thread.currentThread().getName()+":"+x);
		}
	}

 

 跟線程優先級相關的方法:

  public final int getPriority()返回線程的優先級。

  public final void setPriority(int newPriority)更改線程的優先級

  線程存在一個默認優先級

 public static final int MAX_PRIORITY 10 最大優先級

 public static final int MIN_PRIORITY 1 最小優先級

 public static final int NORM_PRIORITY 5 默認優先級

 public final void join():等待該線程終止 interruputedException 中斷異常

 分別創建三個子線程,讓第一個子線程執行之後,調用join()等待該線程中,在執行t2,t3線程

public static void sleep(long millis):線程睡眠 指定是時間毫秒值

   throws InterruptedException

public void run() {
		for(int x = 0 ; x <100 ; x ++) {
			//t1,t2
			//t1, 0,1    //t2來了 ,3,4,5,6,7,8	//t1 2 ,,,
			System.out.println(getName()+":"+x+",日期是:"+new Date());
			
			//困了,想睡十秒鐘
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

  兩個區別?

public final void stop() ;強迫線程停止執行。 不會執行了 (過時了),方法能使用的

public void interrupt()中斷線程。 表示中斷線程的一種狀態

public final void stop() ;強迫線程停止執行。 不會執行了 (過時了),方法能使用的

 public static void yield()暫停當前正在執行的線程對象,並執行其他線程

public static void main(String[] args) {
		
		//創建ThreadStop類對象
		ThreadStop st = new ThreadStop() ;
	
		st.start() ;
		
		//如果3秒不醒來,我就幹掉你
		try {
			st.sleep(3000);
//			st.stop();
			st.interrupt();// 中斷
		} catch (InterruptedException e) {
//			e.printStackTrace();
			System.out.println("程序出現了中斷異常");
		}	
	}

實現多線程程序的第二種方式:

  1)自定義一個類,實現Runnable接口

  2)實現接口中的run方法,對耗時的代碼進行操作

  3)然後在主線程中創建該了對象,將該類對象做爲一個資源類,創建Threadd類的對象,將剛纔的資源類作爲參數進行傳遞

public class MyThread implements Runnable {

	@Override
	public void run() {
		
		for(int x= 0; x <100 ; x ++) {
//			System.out.println(getName()+":"+x);
			System.out.println(Thread.currentThread().getName()+":"+x);
		}
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章