88.序列流java
注意:寫入讀取的對象必須實現序列化接口Serializable才能夠,不然會報錯服務器
一旦序列化的類有改變,以前的序列化就無效了出現報錯,類再也不匹配,須要設置UID併發
默認狀況下Intellij IDEA關閉了繼承了Java.io.Serializable的類生成serialVersionUID的警告,若是須要提示生成serialVersionUID,那麼須要作如下設置:在Editor->Inspections下勾選中Java->Serialization issues->Serializable class without ‘serialVersionUID’,將光標放到類名上按Atl+Enter鍵就會提示生成serialVersionUID了 異步
import java.io.Serializable; public class Person implements Serializable{ //設置UID private static final long serialVersionUID = -7911922289599340825L; private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
序列化流ide
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class ObjectOutputStreamDemo { public static void main(String[] args) { ObjectOutputStream o=null; try { o=new ObjectOutputStream(new FileOutputStream("person.txt")); Person p=new Person("大名",20); Person p1=new Person("大華",16); Person p2=new Person("小可",12); o.writeObject(p); o.writeObject(p1); o.writeObject(p2); } catch (IOException e) { e.printStackTrace(); } finally { if(o!=null){ try { o.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
反序列化一次只能讀取一個,讀完了再讀就會報錯this
import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class ObjectInputSreamDemo { public static void main(String[] args) { ObjectInputStream in=null; try { in=new ObjectInputStream(new FileInputStream("person.txt")); Object o=in.readObject(); Person p=(Person)o; System.out.println(p.getName()); System.out.println(o); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if(in!=null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
解決辦法,放入集合中編碼
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; public class ObjectOutputStreamDemo1 { public static void main(String[] args) { ObjectOutputStream o=null; try { o=new ObjectOutputStream(new FileOutputStream("person1.txt")); List<Person> personlist=new ArrayList<>(); Person p=new Person("大名",20); Person p1=new Person("大華",16); Person p2=new Person("小可",12); personlist.add(p); personlist.add(p1); personlist.add(p2); o.writeObject(personlist); } catch (IOException e) { e.printStackTrace(); } finally { if(o!=null){ try { o.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
import sun.text.resources.cldr.om.FormatData_om; import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.util.List; public class ObjectInputSreamDemo1 { public static void main(String[] args) { ObjectInputStream in=null; try { in=new ObjectInputStream(new FileInputStream("person1.txt")); Object o=in.readObject(); List<Person> p=(List<Person>)o; //所有讀取 System.out.println(p); //遍歷逐個讀取 for (int i = 0; i < p.size(); i++) { System.out.println(p.get(i).getName()); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if(in!=null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
89.字符編碼spa
存儲:線程
在計算機中存儲字符都是存儲的字符所對應的數值以二進制的形式表示。3d
展現:
去相關的編碼表中去查找該值(存儲的值)所對應的字符。
通常是默認UTF-8碼錶
經常使用碼錶:
ASCII表:用7bit來表示存儲數據
ISO-8859-1:拉丁碼錶, 用8bit來表示
GB2312: 簡體中文編碼(國標碼)
GBK:gb2312作了加強
GB18030:對GBK作了加強
BIG5:支持繁體
Unicode:支持多種國家的語言,這是國際標準。用2個字節來存儲。 無論是什麼字符都用2個字節,會有浪費。
UTF-8: 支持多種國家的語言,針對不一樣的字符的範圍給出不一樣的字節表示。0,a,A用一個字符存儲;中間的範圍用二個字節 ;中文就使用3個字節。
寫入的編碼和讀取的編碼必需要一致,不然會有亂碼。
90.線程
重點:(1)熟練掌握線程的兩種實現方式,第一種必須聲明爲Thread的的子類重寫run方法,run()是線程執行的邏輯體,啓動線程是異步啓動調用start(),能夠經過調用getName()得到線程的名字;第二種建立方法是實現Runable接口,實現run方法重寫,將子類做爲參數傳入線程對象的建立中;
(2)線程的生命週期:
(3)線程中出現的問題:併發問題使用同步代碼,須要知足:代碼被多個線程訪問,代碼中有共享的數據,共享數據被多條語句操做。
單獨做爲代碼塊,能夠放在方法中,return的位置不受影響,語法:
synchronized(鎖對象){
//操做共享資源的代碼
}
修飾在方法上注意兩種線程建立方式的不一樣
(4)休眠:在作服務器端的程序的時候都須要給一個休眠的時間,在沒有synchronized代碼塊裏面會讓出cpu的資源。有sychronized代碼塊裏面繼續佔用CPU資源
(5)線程間的通訊;
注意:
1.線程間的通訊共享數據必定要有同步代碼塊synchronized
2.必定要有wait和notify,並且兩者必定是成對出現。
3.生產者和消費者的線程實現必定是在while(true)裏面
(6)設置優先級setPriority(Thread.MAX_PRIORITY),優先執行
(7)線程的加入,join(),必須放在須要優先執行的線程start()下面
(8)讓出線程,Thread.yield()
(9)守護線程,主線程結束,線程也再也不繼續執行,setDaemon(true)
(10)死鎖,線程鎖裏面的線程鎖,須要避免的
package s20190523; public class MyThread extends Thread{ private String name; public MyThread(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(this.name+" 正在加載 "+i+"%!"); try { //休眠,讓出CPU資源 Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }
public class ThreadDemo { public static void main(String[] args) { MyThread t=new MyThread("逗鳥外傳萌寶大做戰"); MyThread t1=new MyThread("我不喜歡這世界我只喜歡你"); t.start(); t1.start(); } }
public class MyThread1 implements Runnable{ private String name; public MyThread1(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(name+" 正在加載 "+i+"%!"); } } }
public class ThreadDemo1 { public static void main(String[] args) { Thread t=new Thread(new MyThread1("逗鳥外傳萌寶大做戰")); Thread t1=new Thread (new MyThread1("我不喜歡這世界我只喜歡你")); t.start(); t1.start(); } }
public class SaleTickets extends Thread{ //定義共享資源屬性爲類屬性 static int ticket=100; private String name; //定義建立鎖對象,這個對象是多個線程對象共享的數據 static Object obj=new Object(); public SaleTickets(String name) { this.name = name; } @Override public void run() { //同步代碼避免併發問題 while(true){ synchronized (obj){ if(ticket>0){ System.out.println(this.name+"售出座位號"+(ticket--)+"火車票!"); }else{ break; } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(this.name+"售罄!"); } }
public class SaleTicketsTest { public static void main(String[] args) { SaleTickets s1=new SaleTickets("1號售票口"); SaleTickets s2=new SaleTickets("2號售票口"); SaleTickets s3=new SaleTickets("3號售票口"); SaleTickets s4=new SaleTickets("4號售票口"); s1.start(); s2.start(); s3.start(); s4.start(); } }
另外一種方法,注意synchronized修飾在對象方法上
public class SaleTickets1 implements Runnable { //定義共享資源屬性 int ticket = 100; //定義建立鎖對象 Object obj = new Object(); public void run() { //賣票是持續的 while (true){ //調用synchronized修飾的對象方法 if (saleTickets()) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } //synchronized修飾在對象方法上 public synchronized boolean saleTickets(){ boolean flag=false; if(ticket>0){ System.out.println(Thread.currentThread().getName() + "賣出座位號爲" + (ticket--) + "的票"); }else{ System.out.println(Thread.currentThread().getName()+"售罄!"); flag=true; } return flag; } }
public class SaleTicketsTest1 { public static void main(String[] args) { SaleTickets1 s=new SaleTickets1(); Thread s1=new Thread(s,"1號售票口"); Thread s2=new Thread(s,"2號售票口"); Thread s3=new Thread(s,"3號售票口"); Thread s4=new Thread(s,"4號售票口"); s1.start(); s2.start(); s3.start(); s4.start(); } }
public class Basket { //設置一個籃子是否爲空的屬性 private boolean isEmpty; //解封這個屬性設置 public void setEmpty(boolean empty) { isEmpty = empty; } //建立籃子是否爲空的方法 public boolean isEmpty() { return isEmpty; } }
public class Producer extends Thread{ Basket basket=new Basket(); public Producer(Basket basket) { this.basket = basket; } @Override public void run() { //必定是在while(true)以內的 while (true){ synchronized (basket){ try { if(!(basket.isEmpty())){ //wait()線程等待 basket.wait(); }else{ System.out.println("生產者生產水果!"); //注意設置籃子狀態不爲空 basket.setEmpty(false); //與wait()成對出現喚醒線程,提醒消費者消費 basket.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
public class Buyer extends Thread{ private Basket basket=new Basket(); public Buyer(Basket basket) { this.basket = basket; } @Override public void run() { while (true){ synchronized (basket){ try { if(basket.isEmpty()){ basket.wait(); }else{ System.out.println("消費者購買水果!"); //注意設置籃子狀態爲空 basket.setEmpty(true); basket.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } }
public class ThreadTest { public static void main(String[] args) { Basket basket=new Basket(); Producer p=new Producer(basket); Buyer b=new Buyer(basket); p.start(); b.start(); } }
另外一種方法
public class Basket { //設置一個籃子是否爲空的屬性 private boolean isEmpty; //解封這個屬性設置 public void setEmpty(boolean empty) { isEmpty = empty; } //建立籃子是否爲空的方法 public boolean isEmpty() { return isEmpty; } }
public class Producer1 implements Runnable{ private Basket basket; public Producer1(Basket basket) { this.basket = basket; } @Override public void run() { //必定是在while(true)以內的 while (true){ synchronized (basket){ try { if(!(basket.isEmpty())){ //wait()線程等待 basket.wait(); }else{ System.out.println("生產者生產水果!"); //注意設置籃子狀態不爲空 basket.setEmpty(false); //與wait()成對出現喚醒線程,提醒消費者消費 basket.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
public class Buyer1 implements Runnable{ private Basket basket; public Buyer1(Basket basket) { this.basket = basket; } @Override public void run() { while (true){ synchronized (basket){ try { if(basket.isEmpty()){ basket.wait(); }else{ System.out.println("消費者購買水果!"); //注意設置籃子狀態爲空 basket.setEmpty(true); basket.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } }
public class ThreadTest1 { public static void main(String[] args) { Basket basket=new Basket(); Producer p=new Producer(basket); Buyer b=new Buyer(basket); Thread t1=new Thread(p); Thread t2=new Thread(b); t1.start(); t2.start(); } }
public class MyThread extends Thread{
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.name+" 正在加載 "+i+"%!");
try {
//休眠,在沒有synchronized代碼塊裏面會讓出cpu的資源。有sychronized代碼塊裏面繼續佔用CPU資源
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MyThreadTest { public static void main(String[] args) { MyThread t1=new MyThread("逗鳥外傳萌寶大做戰"); MyThread t2=new MyThread("我不喜歡這世界我只喜歡你"); MyThread t3=new MyThread("冰雪傳奇"); MyThread t4=new MyThread("瀝川往事"); // 設置優先級 t4.setPriority(Thread.MAX_PRIORITY); t1.start(); t2.start(); t3.start(); t4.start(); } }
public class MyThreadTest { public static void main(String[] args) { MyThread t1=new MyThread("逗鳥外傳萌寶大做戰"); MyThread t2=new MyThread("我不喜歡這世界我只喜歡你"); MyThread t3=new MyThread("冰雪傳奇"); MyThread t4=new MyThread("瀝川往事"); t2.start(); try { //線程加入必須放在須要優先的線程start後面纔有效 t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } t1.start(); t3.start(); t4.start(); } }
import s20190523.MyThread; public class MyThreadTest1 { public static void main(String[] args) { MyThread t1=new MyThread("逗鳥外傳萌寶大做戰"); //設置守護線程,線程隨主線程結束而結束 t1.setDaemon(true); t1.start(); System.out.println("主線程結束"); } }
public class Lock { static Lock lock1=new Lock(); static Lock lock2=new Lock(); }
public class DeadLock extends Thread{ int flag; @Override public void run() { if (flag==1){ synchronized (Lock.lock1){ System.out.println("進入鎖1"); synchronized (Lock.lock2){ System.out.println("進入鎖1中的鎖2"); } } }else{ synchronized (Lock.lock2){ System.out.println("進入鎖2"); synchronized (Lock.lock1){ System.out.println("進入鎖2中的鎖1"); } } } } }
public class DeadLockTest { public static void main(String[] args) { DeadLock l1=new DeadLock(); DeadLock l2=new DeadLock(); l1.flag=1; l1.start(); l2.start(); } }