JAva学習ノート(十七)

7022 ワード

一、プログラム、プロセスとスレッド
プログラム:論理+データ、実行されていない命令シーケンスと関連するデータのセット(qq.exe;ディスク上の実行可能コマンドなど)
プロセス:実行中のプログラム、プロセス占有リソース(CPU,Memory,IO)
スレッド:プロセス内で同時実行されるプロセス(共有プロセスリソース)
同期:歩調が一致する順序で実行され、上記のようにバスが1つずつ乗車します.
非同期:歩調が合わない同期実行、例えば:みんなでトラックに乗る
スレッド:名詞->クラス
1.Threadクラスにメソッドrun()が含まれています.このメソッドは独立して実行されるプロセスです(匿名の内部クラスでrun()を上書きできます).
2.Threadクラスには、独立したrun()を起動するためのメソッドstart()も含まれています.
スレッドを作成します.
1.Threadのrun()メソッドを上書きし、独立して実行するプロセスを提供する(方式が複数ある)
2.Threadインスタンスを呼び出すstart()メソッドrun()プロシージャの起動
例:
public static void main(String[] args) {
		MyThread t=new MyThread();
		YourThread t2=new YourThread();
		t.setDaemon(true);
		t2.setPriority(Thread.MAX_PRIORITY-1);<span style="white-space:pre">				</span>//9
		t.start();							//  run  
		Thread.yield();<span style="white-space:pre">							</span>//         
		t2.start();
		System.out.println("Over");
	}
}
//       run()  
class MyThread extends Thread{
	public void run(){
		for(int i=0;i<100;i++){
			System.out.println("         ,      ");
			if(i%2==0){
				Thread.yield();
			}
		}
	}
}
class YourThread extends Thread{
	public void run(){
		for(int i=0;i<100;i++){
			System.out.println("    ?");
		}
	}
}

二、スレッド
(一)スレッドの状態:
1.new(新規)
2.Runnable
3.Running
4.Block
5.Died
(二)スレッド状態管理
1.Thread.yield()現在のスレッドはプロセッサを譲って(runningを離れて)、現在のスレッドをRunnableに入って待つ
2.Thread.sleep(times)現在のスレッドをrunning放棄プロセッサからBlock状態にし、スリープtimesがこの数ミリ秒後にRunnableに戻る
3.他のスレッドが現在のスレッドのBlock(sleep)を中断すると、InterruptedExceptionが発生します.
4.バックグラウンドプロセス(デーモンスレッド、スプライトスレッド)
JAvaプロセスの終了、すべてのフロントスレッドが終了するとjavaプロセスが終了します.バックグラウンドスレッドは終了するかどうかにかかわらず停止されます
t.setDaemon(true);//tをデーモンスレッドにする
例:
public static void main(String[] args) {
		Thread t=new Thread(){
			public void run(){
				for(int i=0;i<5;i++){
					System.out.println("  ");
					try{
						Thread.sleep(1000);
					}catch(InterruptedException e){
						System.out.println("   ");
						break;
					}
				}
			}
		};
		t.start();
		for(int i=0;i<5;i++){
			System.out.println("  ");
			try{
				Thread.sleep(500);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
		System.out.println("   ");
		t.interrupt();//        t sleep
	}

(三)スレッドの優先度
デフォルトでは10の優先度があり、優先度の高いスレッドは実行する機会が多く、機会の多少はコードで介入できません.デフォルトの優先度は5です.
(四)スレッドの作成方法
1.Threadクラスの継承
a.Threadクラスを継承し、run()メソッドを上書きして同時実行の機会を提供する
b.このクラスのインスタンスを作成する
c.start()メソッドを使用してスレッドを起動する
2.Runnableインタフェースの実装
a.Runnableインタフェースを実現し、run()方法を実現し、同時実行のプロセスを提供する
b.このクラスのインスタンスを作成し、このインスタンスをThreadコンストラクタパラメータとしてThreadクラスを作成する
c.start()メソッドを使用してスレッドを起動する
3.内部クラスを使用したスレッドの作成
使用できるCurrentThread()メソッドは、現在のスレッドの参照を取得します.
例:
public static void main(String[] args) {//         
		new Thread(){
			public void run(){
				for(int i=0;i<5;i++){
					System.out.println("HEY");
				}
			}
		}.start();
		
		new Thread(new Runnable(){
			public void run(){
				for(int i=0;i<5;i++){
					System.out.println("HEY");
				}
			}
		}).start();
	}

例:
public class RunnableDemo {
	public static void main(String[] args) {
		Thread t1=new Thread(new Foo());
		Thread t2=new Thread(new Foo());
		Thread t3=new Thread(new Foo());
		t1.start();
		t2.start();
		t3.start();
	}
}
class Foo implements Runnable{
	public void run(){
		for(int i=0;i<5;i++){
			System.out.println("HEY");
		}
	}
}

(五)スレッド同期
1.複数のスレッドが同じ臨界リソースを同時に読み書きする場合、スレッドセキュリティの問題が発生する
2.同期コードブロックを使用して同期読み書き臨界資源を解決し、同時セキュリティ問題を解決できる
3.a.同期コードブロック
synchronized(this){}
b.同期モニタは任意のオブジェクトインスタンスであり、複数のスレッド間の反発のロックメカニズムであり、複数のスレッドが同じ「モニタ」を使用して同期反発を実現する
c.よくある書き方:
synchronized(this){}
d.メソッドのすべてのプロセスを同期する必要がある場合、synchronized修飾メソッドを簡単に使用できます.
例:
public class SyncDemo {
	int i=1;
	Object monitor=new Object();
	public synchronized int getNumber(){//public synchronized int getNumber=public int getNumber{synchronized(this)}
	//	synchronized (monitor){//  ,    ,     monitor      ,         ,       ,     this  
			if(i==20){
				throw new RuntimeException("Over");
			}
			try{
				Thread.sleep(10);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
			return i++;
		//}
	}
	//      
	public void go(){//     ,            main  ,              
		Thread t1=new MyThread();
		Thread t2=new MyThread();
		t1.start();
		t2.start();
		}
	public static void main(String[] args) {
		new SyncDemo().go();			
	}	
	class MyThread extends Thread{//        
		public void run(){
			while(true){
				System.out.println(getNumber());
			}
		}
	}
}

JAvaで同期されたAPI:
1.StringBufferは同期のsynchronized append()
StringBuilderは同期のappend()ではありません
2.VectorとHashTableの同期
ArrayListとHashMapは同期していません
3.Collection.synchronizedList()
  ArrayList list=new ArrayList()
  List syncList=Collection.synchronizedList(list);
(六)非同期プロセス間のコラボレーション通信
1.ファイルの同時書き込み操作:コンソールから1行を読み込み、すぐにファイルに書き込む
2.非同期でファイルを書く操作を行い、コンソールから1行を読み取り、バッファに入れ、バッファがいっぱいになるか、バッファをタイミングよくチェックし、バッファに内容があるときにファイルに書き込む.
例:
<span style="white-space:pre">	</span>WriteThread w=new WriteThread();
	ReadThread r=new ReadThread();
	
	List<String> buf=new ArrayList<String>();
	class WriteThread extends Thread{
		public void run(){
			try{
				PrintWriter out=new PrintWriter(
						new FileWriter("unsyncio.txt",true));//      
				while(true){
					if(buf.isEmpty()){
						try{
							Thread.sleep(5000);
						}catch(InterruptedException e){}
						continue;
					}
			//		out.println(buf);//         
					for(String str:buf){
						out.println(buf);
					}
					System.out.println("Writing...");
					buf.clear();
					out.close();
				}
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}
	class ReadThread extends Thread{
		public void run(){
			BufferedReader console=
					new BufferedReader(
							new InputStreamReader(
									System.in));
			String str;
			try{
				while((str=console.readLine())!=null){
					buf.add(str);
			//		w.interrupt();
					if("exit".equalsIgnoreCase(str)){
						w.interrupt();
						break;
					}
				}
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}
	public void go(){
		w.setDaemon(true);
		w.start();
		r.start();
	}
	public static void main(String[] args) {
		new UnsyncIODemo().go();

	}

三、Timerタイマー
最下位はスレッドです
例:
public static void main(String[] args) {
		Timer t=new Timer();
		t.schedule(new TimerTask(){
			int i=10;
			public void run(){
				System.out.println("  "+i--);
				if(i==0){
					t.cancel();
					System.out.println("      ");
				}
			}
		}, 1000,5000);

	}