Java——多線程基本使用(二)

在學習多線程時,如果聯繫操作系統來學習,會覺得很好理解。因爲學習操作系統時候,有同步,互斥,鎖的一些概念~

給個鏈接到上一篇~https://blog.csdn.net/zoweiccc/article/details/83002176

8.加入線程

      (1)join,當前線程暫停,等待指定的線程執行結束後,當前線程再繼續

      (2)join(int),可以等待指定的毫秒之後繼續,交替繼續

9.禮讓線程

      yield讓出cpu

10.設置線程的優先級,最小的優先級是1,最大是10,默認是5

      setPriority()

11.什麼情況下需要使用同步

      如果多線程併發,有多段代碼同時執行時,我們希望某一段代碼執行的過程中cpu不要切換到其他線程工作,這時就需要同步

      如果兩段代碼是同步的,那麼同一時間只能執行一段,在一段代碼沒執行結束之前,不會執行另一段代碼

12.同步代碼塊

      使用synchronize關鍵字加上一個鎖對象來定義一段代碼,就叫做同步代碼塊

      多個同步代碼塊如果使用相同的鎖對象,那麼他們就是同步的

13.同步方法

      使用synchronized關鍵字修飾的一個方法,該方法中所有的代碼都是同步的

      非靜態的同步方法的鎖對象是this,靜態的同步方法的鎖對象是該類的字節碼對象,即Pr2.class

14.線程安全問題,用火車站售票例子解釋

15.死鎖:多線程同步時,如果同步代碼嵌套,使用相同鎖,就有可能出現死鎖,爲了避免,不要出現同步代碼塊嵌套

16.一般來說,通過查看類的源碼,如果存在synchronized,則大部分可認爲是線程安全的。

      比如:Vector是線程安全的,ArrayList是線程不安全的

               StringBuffer是線程安全的,StringBuilder是線程不安全的

               Hashtable是線程安全的,HashMap是線程不安全的

 

package pra_20;
public class J_39 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//8.加入線程
		final Thread th1=new Thread(){	
			public void run(){
				for(int i=0;i<10;i++){
					System.out.println("1");
				}
			}
		};
		Thread th2=new Thread(){
			public void run(){
				for(int i=0;i<10;i++){
					if(i==2){
						try {
							th1.join();		//匿名內部類在使用所在方法中的局部變量時,必須用final修飾
							//th1.join(1)	
						} catch (InterruptedException e) {
							e.printStackTrace();
						}		
					}
					System.out.println("2");
				}
			}
		};
		th1.start();
		th2.start();
		
		//9.禮讓線程
		new Mythread2().start();
		new Mythread2().start();
		
		//10.設置線程的優先級
		Thread th3=new Thread(){
			public void run(){
				for(int i=1;i<1000;i++){
					System.out.println(getName()+"~~~~a");
				}
			}
		};
		Thread th4=new Thread(){
			public void run(){
				for(int i=1;i<1000;i++){
					System.out.println(getName()+"~~~~b");
				}
			}
		};
		th3.setPriority(10);
		th4.setPriority(3);
		th3.start();
		th4.start();
	
		//12.同步代碼塊
		final Pr p1=new Pr();
		new Thread(){
			public void run(){
				while(true){
					p1.pri();	
				}
			}
		}.start();
		new Thread(){
			public void run(){
				while(true){
					p1.pri2();	
				}
			}
		}.start();
		
		//13.同步方法
		final Pr2 p2=new Pr2();
		new Thread(){
			public void run(){
				while(true){
					p2.pri();	
				}
			}
		}.start();
		new Thread(){
			public void run(){
				while(true){
					p2.pri2();	
				}
			}
		}.start();
		
		//14.線程安全問題
		new Ticket().start();
		new Ticket().start();
		new Ticket().start();
		new Ticket().start();
	}
}
class Ticket extends Thread{
	private static int ticket=100;
	public synchronized void run(){
		while(true){
			synchronized(Ticket.class){
			if(ticket<=0)
				break;
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
			System.out.println("這是第"+ticket--+"張票");
			}
		}
	}
	}
//爲了實現同步方法創建的類(非靜態)
class Pr2{
	Suo s=new Suo();
	//非靜態的同步方法的鎖對象是this,靜態的同步方法的鎖對象是該類的字節碼對象,即Pr2.class
	public synchronized void pri(){		//同步方法只需要在方法上加synchronized關鍵字即可
			System.out.print("p");
			System.out.print("q");
			System.out.print("r");
			System.out.print("s");
			System.out.println();	
	}
	public void pri2(){
		synchronized(this){
			System.out.print("a");
			System.out.print("b");
			System.out.print("c");
			System.out.print("d");
			System.out.println();
		}
	}
}
//爲了實現同步方法創建的類(靜態)
class Pr3{
	Suo s=new Suo();
	//靜態的同步方法的鎖對象是該類的字節碼對象,即Pr3.class
	public static synchronized void pri(){		//同步方法只需要在方法上加synchronized關鍵字即可
			System.out.print("p");
			System.out.print("q");
			System.out.print("r");
			System.out.print("s");
			System.out.println();	
	}
	public static void pri2(){
		synchronized(Pr3.class){
			System.out.print("a");
			System.out.print("b");
			System.out.print("c");
			System.out.print("d");
			System.out.println();
		}
	}
}
//爲了實現同步代碼塊創建的類
class Pr{
	Suo s=new Suo();			//這個鎖對象可以是任意的,隨意創建一個對象即可,下面都表示的同一個鎖
	public void pri(){
		synchronized (s) {		//同步代碼塊,鎖機制,當此方法運行完了才允許同步的執行,但參數不能創建匿名對象,因爲匿名不是同一個
			System.out.print("p");
			System.out.print("q");
			System.out.print("r");
			System.out.print("s");
			System.out.println();
		}
	}
	public void pri2(){
		synchronized (s) {
			System.out.print("a");
			System.out.print("b");
			System.out.print("c");
			System.out.print("d");
			System.out.println();
		}
	}
}
class Suo{
}
class Mythread2 extends Thread{
	public void run(){
		for(int i=1;i<1000;i++){
			if(i%10==0){
				Thread.yield();		//讓出cpu
			}
			System.out.println(getName()+"~~~~"+i);
		}
	}
}

 

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