多線程 (基礎)

線程的基礎內容

程序、進程、線程

  • 一個進程中至少有一個線程
    各個應用程序之間去搶佔CPU資源,在同一個時間點上,CPU只能處理一個程序,看上去像是同時在進行,其實是CPU在快速的切換,進程搶佔到CPU資源後,各個線程就去搶,那個線程先搶到就執行那個線程,(所以每一次執行的順序都不一樣)
  • 在java虛擬機上啓動的時候會有一個進程java.exe,該進程中至少有一個線程,在負責java程序的執行。而且這個線程運行的代碼在main方法中,該線程爲主線程
  • 但是線程結束,進程未必結束,但進程結束,線程一定結束,線程是進程中的一部分

線程的創建和啓動

  • 在java中負責線程的這個功能的是java.lang.Thread這個類
  • 可以通過new Thread(創建Thread的實例)來創建新的線程
  • 每個都是通過某個特定Thread對象所對應的run()方法完成其操作,run()方法稱爲線程體。
  • 可以通過調用Thread類的start()方法來啓動一個線程。
  • 繼承Thread類 ,重寫run方法,創建對象,調用start()方法,啓動線程。

代碼如下:

public class A extends Thread{
	@Override
	public void run() {
		System.out.println("我是A");
	}
	public static void main(String[] args) {
		A a=new A();
		Thread t=new Thread(a);
		a.start();
	}
}
    • 創建線程的第二個方式:
  • 實現Runnable接口,重寫run方法,創建對象,啓動線程。

代碼如下:

public class B implements Runnable{
	@Override
	public void run() {
		System.out.println("我是B");
	}
	public static void main(String[] args) {
		B b=new B();
		Thread t=new Thread(b);
//也可以這樣  Thread t=new Thread(new B());
		t.start();
	}
}
  • 以上都是單線程,下面一個多線程的應用:
    賣票
public class ThreadDemo6 implements Runnable{
	int Ticket=5;
	@Override
	public void run() {
		for(int i=0;i<100;i++){
		if(Ticket>0){
		System.out.println(Thread.currentThread().getName()+"正在出售"+(Ticket--)+"車票");
		}
	}
	}
	public static void main(String[] args) {
		ThreadDemo6 t = new ThreadDemo6();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		Thread t3=new Thread(t);
		Thread t4=new Thread(t);
		t1.start();
		t2.start();
		t4.start();
		t3.start();
	}
}

有可能出現這樣的現象:

5張車票,出售了6張
Thread-0正在出售5車票
Thread-2正在出售2車票
Thread-2正在出售1車票
Thread-3正在出售3車票
Thread-1正在出售4車票
Thread-0正在出售0車票

這樣就用到了線程的同步
線程同步

  • 用到了:synchronized,這個可以是同步代碼塊,同步對象。
    線程同步的實現
public class ThreadDemo15 implements Runnable{
	int sum=5;
	@Override
	public synchronized void run() {
		for (int i = 0; i < 200; i++) {
			if(sum>0){
				System.out.println(Thread.currentThread().getName()+"出售"+sum--+"票");
				try {
					Thread.sleep(100);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	public static void main(String[] args) {
		ThreadDemo15 t = new ThreadDemo15();
		Thread t0 = new Thread(t);
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		Thread t3 = new Thread(t);
		t0.start();
		t1.start();
		t2.start();
		t3.start();
	}
}
  • 死鎖
  • 同步可以保證資源共享操作的正確性,但是過多同步也會產生死鎖, 死鎖一般情況下表示互相等待,是程序運行時出現的一種問題。
  • 例如:
    想要畫的張山跟想要書李四說:“把你的畫給我,我把我的書給你”,李四也說:“把書給我,我把畫給你”。然後倆個人互相等待
    線程間通信

    線程間通信的實現
public class communication01 {
    public static void main(String[] args){
        final besiness b=new besiness();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=1;i<=50;i++){
                    b.sub(i);
                }
            }
        }).start();
        for (int i = 1; i <= 50; i++) {
            b.main(i);
        }
    }
}
 class besiness{
     private static  boolean flag=true;//flag爲true時允許main訪問,爲false時允許suB訪問
        public synchronized void main(int i){
            while(!flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 1; j <= 10; j++) {
                System.out.println("main thread==" + j + ",loop of " + i);
            }
            flag=false;
            this.notify();
        }
        public  synchronized  void sub(int i){
            while (flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 1; j <= 10; j++) {
                System.out.println("sub thread==" + j + ",loop of " + i);
            }
            flag=true;
            this.notify();
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章