マルチスレッドの些細なこと


以前Javaを勉強していたときは、あまりスレッドを研究していませんでしたが、仕事中でもめったに遭遇しませんでした.今から拾って勉強します.マルチスレッドとは何か、プロセスと混同されやすいことがよくあります.プログラムが起動すると、プロセスが生成され、プロセスの下に複数のスレッドが同期または非同期で実行されます.
マルチスレッドを実装する2つの方法は,JavaにおいてRunableインタフェースの実装とThreadクラスの継承によって実現できる.
継承方法:
public class MyThread  {
	public static void main(String[] args) {
		TestThread testThread=new TestThread("test thread");
		testThread.start();		
		for (int i = 0; i < 100; i++) {
			System.out.println("main"+i);
		}
	}
}
class TestThread extends Thread{
	public TestThread(String name){
		super(name);
	}
	@Override
	public void run() {
		//               
		int index=0;
		for (; index < 10; index++) {
			System.out.println(this.getName()+index);
		}
	}
}
1.継承thread
2.runメソッドを上書きし、runメソッドのコードはマルチスレッドベースである
3.このクラスを作成するオブジェクト呼び出しstartメソッド起動スレッド
インタフェース:
public static void main(String[] args) {
		
		ThredInterface interface1=new ThredInterface();
		try {
			interface1.begin();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	class Mythread2 implements Runnable{
		int index=0;
		private boolean flag=true;
		@Override
		public void run() {
			
			//          
			//      ,       
			for (index=0; index < 2000; index++) {
				if(!flag)break;
				System.out.println(Thread.currentThread().getName()+index);
			}
		}
		
		public void stopThread(){
			//    
			
			flag=false;
		}
	}
1.runableインタフェースの実装
2.runメソッドを上書きし、runメソッドのコードはマルチスレッドベースである
3.runableインタフェースを実装するにはstartメソッドがないため、runableインタフェースを実装するクラスを1つのThreadに配置して実行する
区別:メンバー変数、継承方法、各スレッドのメンバー変数には記憶領域があり、インタフェースの方法はすべてのスレッドが1つのメンバー変数を共有し、交互に実行します.
開発ではインタフェース方式呼び出しが一般的に用いられる.継承方式を用いると,そのクラスは他のクラスを継承することができず,インタフェースを実現し,複数のインタフェースを実現することができるからである.
一般的な方法:
スレッドの名前を設定
threadの構築方法の最初のパラメータはrunableインタフェースを実現するクラスであり、2番目のパラメータはスレッド名public Thread(Runnable target,String name){init(null,target,name,0);    }
スレッド名の取得:Thread.currentThread().getName()スレッドスケジューリング:th.join();//ずっと交代しないで、現在のスレッドはthを歩かなければならない.yield();//一時的に待ち、今回のプリエンプトには参加しません-->runableステータスへ
しかし、スレッドのスケジューリングはこの2つの方法だけでsleepスリープstop停止スレッドを制御することはできません.安全ではないので、自分で停止方法を書いてリソースを解放し、stopスレッドを定義する方法でリソースを解放することをお勧めしません.
スレッドの状態:Runable runing blocked
スレッド同期:synchronizedを使用して、メソッド宣言時にタグを付けることも、スレッド同期ブロックとしてkeyを使用することもできます.
synchronized (this) {
			Mythread2 m=new Mythread2();
			Thread th=new Thread(m,"  1");
			//Thread th2=new Thread(m,"  2");
			th.start();
			//th2.start();
			while (true) {
				if (m.index==1000) {
					System.out.println("tingzhi");
					th.stop(); //   
					m.stopThread();
					break;
				}
			}
		}

同期は効率を失い、後続のすべてのスレッドが待機し、同期の原子性が小さくなり、効率が向上しますが、同期を使用する場合は、複数のスレッドが同じ変数を変更する必要があります.
デッドロックデッドロック:同期のネストされたとき、スレッド間で解決が待機します.同期の原子間増幅は、効率を低下させ、同期と効率のデッドロックプログラムを両立させます.
public static void main(String[] args) {
		new TestLock().run();
	}
	
	public void run(){
		LockThread lockThread=new LockThread();
		new Thread(lockThread,"   ").start();
		new Thread(lockThread,"   ").start();
	}
	class LockThread implements Runnable{

		private Object k1=new Object();
		private Object k2=new Object();
		private boolean flag=true;
		@Override
		public void run() {
			if (flag) {
				flag=false;
				synchronized (k1) {
					System.out.println(Thread.currentThread().getName()+"k1");
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					synchronized (k2) {
						System.out.println(Thread.currentThread().getName()+"k2");
					}
				}
				
			}else{
				flag=true;
				synchronized (k2) {
					System.out.println(Thread.currentThread().getName()+"k2...");
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					synchronized (k1) {
						System.out.println(Thread.currentThread().getName()+"k1");
					}
				}							
			}
			
		}
		
	}