多線程
線程時進程中一個獨立的控制單元,線程在控制着進程的執行。
一個進程至少有一個線程
JVM啓動的時候會有一個進程java.exe
該進程中至少一個線程負責java程序的執行
而且這個線程運行的代碼存在於main方法中,爲主線程
class ThreadDemo extends Thread {
public void run(){
}
}
繼承一個Thread類:1.定義類繼承Thread類2.複寫run方法3.調用start()方法
ThreadDemo d=new ThreadDemo();
d.start();//開啓線程並執行該線程的run方法
每次運行結果都不是一樣的,因爲多個線程都獲取cpu的執行權,互相搶奪cpu資源。
Thread類用於描述線程,該類定義了一個功能,用於存儲線程要運行的代碼,該代碼就是run方法
wait(),notify(),sleep(time),stop()
Thread.currentThread().getName();當前線程
/*
賣票程序,多個窗口都能賣票
**/
class TicketSell extends Thread{
private static int tick=100;//使用靜態
public void run(){
while(true){
if(tick>0){
System.out.println(Thread.currentThread().getName()+"sale"+tick--);
}
}
}
}
class TicketDemo{
public static void main(String[] args){
TicketSell t1=new TicketSell();
TicketSell t2=new TicketSell();
TicketSell t3=new TicketSell();
TicketSell t4=new TicketSell();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
---------------------------------------------------------
1.定義實現Runnable接口
2.覆蓋run方法
3.通過Thread類建立線程對象
4.將Runnable接口的子類作爲對象傳給Thread類的構造函數
5.調用Thread類的start方法開啓線程並調用Runnable接口
class TicketSell implements Runnable{//extends Thread{
private static int tick=100;//使用靜態
Object obj=new Object();
public void run(){
while(true)
{
Synchronized(obj){
if(tick>0){
System.out.println(Thread.currentThread().getName()+"sale"+tick--);
}
}
}
}
}
class TicketDemo{
public void main(String[] args){
TicketSell s=new TicketSell();
Thread t=new Thread(s);
t.start();
}
}
多線程的安全問題
當多條語句在操作同一個線程共享數據時,一個線程對多條語句只執行了一部分,另一個線程參與進來執行
導致共享數據的錯誤。
同步代碼塊
synchronized(對象){
需要被同步的代碼;
}
同步函數,sychronized修飾符修飾函數 就可以了
同步函數使用的鎖匙this
靜態同步函數使用的鎖不是this,因爲靜態方法中不可以定義this
靜態進內存是,內存中沒有本類對象,但是一定有類對應的字節碼文件對象
類名.class 該對象的類型是class
單例設計模式,懶漢式
1. class Single{
private Single(){}
public static Single s=null;
public static synchronized Single getInstance(){
if (s==null)
s=new Single();
}
}
2. class Single{
private Single(){}
public static Single s=null;
public static Single getInstance(){
synchronized(Single.class){
if (s==null)
s=new Single();
}
}
}
3.更高效的方法
class Single{
private Single(){}
public static Single s=null;
public static Single getInstance(){
if(s==null){
synchronized(Single.class){
if (s==null)
s=new Single();
}
}
}
}
死鎖:同步中嵌套同步,但是鎖卻不同
進程間的通信:多個線程在操作同一個資源,但是操作的動作不同
等待喚醒機制
notifyAll();wait();notify();必須都要使用在同步中
用synchronized中的對象來標記