【Java】day 23--同期関数、デーモンスレッド、スレッド通信、IPアドレスクラスの知識点のまとめ

9082 ワード

(一)同期関数
同期関数:synchronizedを使用してこの関数を修飾する同期関数と呼ばれる同期関数の注意点:1.非静的同期関数のロックオブジェクトはthisオブジェクトであり、静的同期関数のロックオブジェクトは現在属するクラスのclassファイルオブジェクトである.(いずれかのclassファイルがメモリにロードされると、jvmはclassファイルに対応するオブジェクト記述を作成します.(方法領域では、1つのみ、ロック対象として使用可能)2.同期関数のロック対象は固定されており、変更できません.推奨使用:同期コードブロック理由:1.同期コードブロックのロック対象は自分で作成できますが、同期関数のロック対象は固定されています.2.同期コードブロックはどの範囲が同期する必要があるかを任意に指定できますが、同期関数は、関数全体が同期している必要があります.コードが柔軟ではありません.
class getCash extends Thread{
	static int money=5000;//    
	static Object o=new Object();
	public getCash(String name) {
		super(name);//             ,      
	}
	//       
	//        ---    this(),                
	@Override
	public synchronized void run() {
		while(true) {
			//synchronized (o) {
				if(money>0) {
					money-=100;
					System.out.println(Thread.currentThread().getName()+"  100 ,  "+money+" ");
				}else {
					System.out.println("5000     ...");
					break;
				}
			//}
		}
	}
	//      -----        class    
	public synchronized static void run1() {
		
	}
}
public class demo5 {

	public static void main(String[] args) {
		//      
		getCash wife=new getCash("      ");
		getCash husband=new getCash("     ");
		//    
		wife.start();
		husband.start();
	}
}

(二)デッドロック現象
JAva同期メカニズムはスレッドセキュリティの問題を解決したが,デッドロック現象も引き起こした.デッドロック現象はできるだけ避けるしかなく、解決できません.デッドロック現象の根本原因:1.マルチスレッドが存在します.    2.複数のスレッドは、2つ以上のリソースを共有する必要があります.(待つ場合がある)
(三)スレッドの第二の作成方法
カスタムスレッドの作成方法:方法1:1.クラス継承をカスタマイズします.        2.サブクラスはrunメソッドを書き換え,カスタムスレッドのタスクをrunメソッドに定義する.        3.threadサブクラスのオブジェクトを作成し、startメソッドを呼び出してスレッドを開きます.方式二:1.クラス実装Runnableインタフェースをカスタマイズします.        2.Runnableインタフェースの方法を実現し,カスタムスレッドのタスクをrunメソッドに定義した.        3.Runnableインプリメンテーションクラスのオブジェクトを作成します.        4.Threadオブジェクトを作成し、Runnable実装クラスオブジェクトをパラメータとして渡す.Threadオブジェクトのstartメソッドを呼び出してスレッドを開きます.
Runnableの実装クラスオブジェクトはスレッドオブジェクトですか?Runnableの実装クラスオブジェクトはスレッドオブジェクトではなく,Runnableインタフェースを実装したオブジェクトである.(Threadクラスとそのサブクラスのオブジェクトのみがスレッドオブジェクト)なぜRunnable実装クラスのオブジェクトをパラメータとしてThreadオブジェクトに渡すのでしょうか?役割とは何ですか?役割:Runnable実装クラスのオブジェクトのrunメソッドをタスクコードとして実行します.推奨使用:第2のスレッド作成方式.javaは単一継承ですから.
public class demo2 implements Runnable{

	@Override
		public void run() {
			for(int i=0;i<100;i++) {
				System.out.println(Thread.currentThread().getName()+":"+i);
			}
			System.out.println("      :"+Thread.currentThread());//    :t
			System.out.println("    :"+this);//this  :d,       
		}
	public static void main(String[] args) {
		//  Runnable      
		demo2 d=new demo2();
		//  Thread  ,  Runnable             
		Thread  t=new Thread(d,"  ");
		//  Thread   start      。
		t.start();
		/*
			1.Thread    target     Runnable     。
			run               。
		 * 
		 * */
		//      
		for(int i=0;i<100;i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
}

(四)デーモンスレッド
デーモンスレッド(バックグラウンドスレッド):javaアプリケーションがデーモンスレッドしか残っていない場合、デーモンスレッドはすぐに終了します.デーモンスレッドのアプリケーションシーン:1.新しいソフトウェアバージョンがダウンロードされます.需要:シミュレーションqqダウンロード更新パッケージ
デーモンスレッドの注意点:1.すべてのスレッドのデフォルトはデーモンスレッドではありません.
ublic class demo4 extends Thread{
	
	public demo4(String name) {
		super(name);
	}

	@Override
		public void run() {//                        
			for(int i=0;i<100;i++) {
				System.out.println(this.getName()+"     :"+i+"%");
				//       ,    (          ,        )
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.println("    ,       ...");
		}
	public static void main(String[] args) {
		//      
		demo4 d=new demo4("    ");
		d.setDaemon(true);//           
		System.out.println("      ?"+d.isDaemon());//isDaemon                
		//    
		d.start();
		for(int i=0;i<100;i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
		//main      ,       ,      ,    。
	}
}

(五)join方法
joinメソッド:スレッド譲歩.需要:子供の頃の醤油打ちをシミュレートします.
class Mother extends Thread{
	@Override
	public void run() {
		System.out.println("    ");
		System.out.println("    ");
		System.out.println("         。。。");
		//        
		Son s=new Son();
		s.start();
		try {
			s.join();//   Mother    
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("    ");
		System.out.println("      ");
	}
}
class Son extends Thread{
	@Override
	public void run() {
		try {
			System.out.println("     ");
			Thread.sleep(1000);
			System.out.println("     ");
			System.out.println("    ");
			System.out.println("   ");
			Thread.sleep(1000);
			System.out.println("      ");
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
}
public class demo5 {

	public static void main(String[] args) {
		Mother m=new Mother();
		m.start();
	}
}

(六)スレッド通信
スレッド通信:あるスレッドがタスクを完了した場合、別のスレッドに他のことを処理するように通知します.スレッド通信の方法:wait()がwaitメソッドを実行したスレッドは、オブジェクトをロックするために確立されたスレッドプールにスレッドを入れて待機させます.notify()スレッドがnotifyメソッドを実行すると、オブジェクトをロックするために確立されたスレッドプールでスレッドを待つスレッドの1つが呼び出されます.notifyAll()はすべてのスレッドを起動します.(ロックオブジェクトを識別するスレッドプール内のスレッド)スレッド通信で注意すべき事項:1.wait notify notifyメソッドはいずれもObjectオブジェクトに属するメソッドである.wait notifyメソッドは、同期コードブロックまたは同期関数で呼び出す必要があります.(ロックオブジェクト)3.wait notifyメソッドは、ロックオブジェクトによって呼び出される必要があります.そうしないと、エラーが発生します.(ロック対象識別スレッドプールが必要)4.1つのスレッドがwaitメソッドを実行すると、ロック対象が解放されます.1つのスレッドがwaitメソッドを実行すると、そのスレッドはロック対象を識別するスレッドプールに入って待機します.1つのスレッドがnotifyメソッドを実行すると、ロック対象で作成されたスレッドプールの待機スレッドの1つが呼び出されます.
需要:生産者は製品を生成し、消費者は1つ消費する.
//   
class Product{
	String name;
	int price;
	boolean flag;//        ,false   
}
//    
class Producer extends Thread{
	public Producer(Product p) {
		this.p=p;
	}
	//      
	Product p;
	//    
	@Override
	public void run() {
		int i=0;
		while(true) {
			synchronized (p) {//     
				if(p.flag==false) {
					if(i%2==0) {
						p.name="   ";
						p.price=4000;
					}else {
						p.name="   ";
						p.price=300;
					}
					System.out.println("   "+p.name+"   :"+p.price);
					i++;
					//    --   
					p.flag=true;
					//       
					p.notify();
				}else {
					//          ,         ,   
					try {
						p.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}	
			}	
		}
	}
}
//    
class Consumer extends Thread{
	//      
	Product p;
	public Consumer(Product p) {
		this.p=p;
	}
	@Override
	public void run() {
		while(true) {
			synchronized (p) {
				if(p.flag==true) {
					System.out.println("      "+p.name+",  "+p.price+" ");
					//   
					p.flag=false;
					p.notify();
				}else {
					//         
					try {
						p.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}	
		}
	}
}
public class demo6 {

	public static void main(String[] args) {
		//        
		Product p=new Product();
		//      (   p)
		Producer producer=new Producer(p);
		Consumer consumer=new Consumer(p);
		//    
		producer.start();
		consumer.start();
	}
}

(七)停止スレッド
停止スレッド:注意事項:1.停止スレッドは一般的に変数によって制御されます.        2.待機状態のスレッドを停止する場合はinterruptメソッドに合わせる必要があります.
public class demo7 extends Thread{

	boolean flag=true;
	public demo7(String name) {
		super(name);
	}
	@Override
	public synchronized void run() {
		int i=0;
		while(flag) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				System.out.println("     InterruptedException");
				//e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+":"+i);
			i++;
		}
	}
	public static void main(String[] args) {
		//      
		demo7 d=new demo7("  ");
		d.start();
		//     i 80   ,      
		for(int i=0;i<100;i++) {
			if(i==80) {
				//d.stop();//    ,    
				d.flag=false;
				d.interrupt();//         wait sleep  ,          , notify    
				/*
				synchronized (d) {
					d.notify();
				}
				*/
			}
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
}

(八)IPアドレス類
JAvaはオブジェクト向けの言語なので、javaはクラスを使用してIPアドレスを記述します.
InetAddress IPアドレスクラスで把握する方法:static getLocalHost()ネイティブipアドレスオブジェクトgetByName(String host)指定文字列形式のipアドレスまたはホスト名を返してipアドレス対象String getHostName()を作成するホスト名getHostAddressを返し、ネイティブipアドレス文字列の表示形式getAllByName(String host)を返します.
public class demo1 {

	public static void main(String[] args) throws UnknownHostException {
		InetAddress address=InetAddress.getLocalHost();//      ip    
		//InetAddress address=InetAddress.getByName("jjjj");//      ,   
		System.out.println("   ip  :"+address.getHostAddress());
		System.out.println("   :"+address.getHostName());
		InetAddress[] address1=InetAddress.getAllByName("https://www.baidu.com");
		
		//System.out.println(Arrays.toString(address1));
	}
}