Javaの研究ノート:マルチスレッド2

1、ロックとの使用のロックの概要
、概要:我々は、同期ロックオブジェクトコードブロックと同期方法の問題を理解することができますが、より明確にするために、ロックが解除されたロックを、追加する場所を我々は直接見えませんがロックとロックを解除する方法の発現は、JDK1.5は後で新しいロックオブジェクトのロックを提供
B、ロックとReentrantLockのを

  • ReentrantLockのは:synchronizedメソッドや文を使用してロック暗黙のモニターを持つリエントラントミューテックスロックは、同じ基本的な動作とセマンティクスが、より強力なアクセス。
  • ロック:実装は、synchronizedメソッドや文の操作よりも利用でき、より広範なロックを提供しています。この実装は、より柔軟な構成を可能にする、非常に異なる特性を有することができ、複数の関連した条件オブジェクトをサポートすることができます。

C、ロックは使用をロック

public class MyThread implements Runnable { 	    	
	private static int tickets = 100 ;	// 定义票数  
    private static final Lock lock = new ReentrantLock() ;  // 创建Lock锁对象
    @Override
	public void run() {		
	while(true){			
		lock.lock() ;	// 添加锁		
		if(tickets > 0){				
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}				
			System.out.println(Thread.currentThread().getName() + "正在出售" + (tickets--) + "张票");				
		}			
		lock.unlock() ;	// 释放锁		
	}		
  }
}
public class MyThreadDemo {
  	public static void main(String[] args) {		
	   // 创建MyThread类的对象
	   MyThread mt = new MyThread() ;		
    	// 创建3个线程对象
	   Thread t1 = new Thread(mt , "窗口1") ;
	   Thread t2 = new Thread(mt , "窗口2") ;
	   Thread t3 = new Thread(mt , "窗口3") ;		
	   // 启动线程
	   t1.start() ;
	   t2.start() ;
	   t3.start() ;				
    }
}

2、デッドロックの問題の概要と使用し
、概要を:同期はデッドロックの問題が原因やすく、できるネストされたとき、それぞれが生成されたリソースの競合によるプロセスの実施、2つの以上のスレッドを指し、現象を待っています。
デッドロック:2つの以上のスレッドCPUのの実行をつかむための時間で、待機状態である
B、ケースプレゼンテーション

class ObjectUtils {
    //定义两把锁
    public static final Object objA=new Object();
    public static final Object objB = new Object();
}
class MyThread extends Thread {
boolean flag;
public MyThread(boolean flag) {
    this.flag = flag;
}
@Override
public void run() {
    if (flag) {
        synchronized (ObjectUtils.objA) {
            System.out.println("true 进来了 持有objA");
            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //阻塞
            synchronized (ObjectUtils.objB) {
                System.out.println("true 进来了 持有objB");
            }
        }
    } else {
        synchronized (ObjectUtils.objB) {
            System.out.println("false 进来了 持有objB");
            //阻塞
            synchronized (ObjectUtils.objA) {
                System.out.println("false 进来了 持有objA");
            }
         }
     }
  }
}
public class MyDemo {
   public static void main(String[] args) throws InterruptedException {
      MyThread th1 = new MyThread(true);
      MyThread th2 = new MyThread(false);
      th1.start();
      th2.start();
  }
}
输出结果:true 进来了 持有objA
         false 进来了 持有objB
原因:在执行了第一条程序后,相互持有了对方的锁而未释放,导致程序发生阻塞不能往下执行

3、スレッド間のウェイクアップ機構を待つ
待機一度、私たちはすぐにロックを解除しなければならない、そして、次のウェイクアップ取引待つどこからどこから目覚めました。

  • 空待ち時間は(); //他のスレッドが()メソッドまたはのnotifyAll()メソッドは、現在のスレッドを待機させ通知にする前にこのオブジェクトを呼び出します。
  • 無効待機(長いタイムアウトが); //他のスレッドが通知にする前にこのオブジェクトを呼び出す()メソッドまたはのnotifyAll()メソッド、または現在のスレッドにつながる時間の指定された量は、待機します。
  • //このオブジェクトのモニターで待機中のスレッドを1つ目を覚ます;ボイド()は通知します。
  • 空のnotifyAll(); //このオブジェクトのモニターで待機中のすべてのスレッドを覚まします。

睡眠と待機方法方法の違い:スレッドを作ることが可能であるがブロックされている
スリープ()時間の量に渡さなければなりません。待機時間は量渡すか、または時間の量を渡すことはできません
睡眠を()スリープにスレッド後、ロックを解放しません。待ち()メソッドに一度我々はロックの解除を待つ必要があります
4、状態遷移図との実装の共通のスレッド
新しい:スレッドが作成される
準備ができて:CPUの資格を実行するが、CPUは、行政権がない
実行するために:CPUが実行する資格があるが、また、CPUの実行を持っています右の
閉塞:CPUが実行するための資格を持っている、またCPUのの執行力があるしない
死:CPUが実行するための資格を持っていませんが、またCPUの執行力がある
ここに画像を挿入説明
5、およびスレッドプールの使用の概要
A、概要:コンテナ、内部をスレッドオブジェクト仕掛けを事前、および効率的な管理を手動で私たち自身のスレッドを作成して、私たちはオブジェクトをスレッドを助けることができる、それが消費する基本的な資源であり、糸の後、死を使用し、再利用することはできません。JDK1.5が与えられた後、我々は唯一のスレッドプールの内部にタスクを提出する必要があり、良いスレッドプールを提供します。

  • スレッドプールのオブジェクトを取得するファクトリクラスで、スレッドプールオブジェクトは、Javaが工場を提供してくれます取得します。

  • ExecutorServiceのExecutorServiceの= Executors.newCachedThreadPool()。

  • JDK5は、次のようにいくつかの方法があり、スレッドプールを生成するエグゼキュータファクトリクラスを追加しました

  • パブリック静的ExecutorServiceのnewCachedThreadPool()の数に対応するタスクのスレッドの数を作成します

  • パブリック静的ExecutorServiceのnewFixedThreadPool(int型にnthreads);固定初期数のスレッド

  • パブリック静的ExecutorServiceのnewSingleThreadExecutor();スレッドプールスレッドを初期化します

B、例えば:

 public class MyDemo {
     public static void main(String[] args) {
     //获取线程池对象
        ExecutorService executorService = Executors.newCachedThreadPool();
        //往线程池中提交任务
        MyRuannable myRuannable = new MyRuannable();
        MyRuannable myRuannable2 = new MyRuannable();
        MyRuannable myRuannable3 = new MyRuannable();
        MyRuannable myRuannable4 = new MyRuannable();
        executorService.submit(myRuannable);
        executorService.submit(myRuannable2);
        executorService.submit(myRuannable3);
        executorService.submit(myRuannable4);
        //关掉线程池 
        executorService.shutdown();    
      }
  }
class MyRuannable implements Runnable{
    @Override
    public void run() {
       System.out.println(Thread.currentThread().getName()+"任务执行了");
    }
}

6、匿名の内部クラスの方法は、マルチスレッドのプログラムを達成するために

public class MyDemo3 {
    public static void main(String[] args) {
        //匿名内部类来创建线程
        //方式1
        new Thread() {
            @Override
            public void run() {
                System.out.println("线程执行了");
            }
        }.start();
        //方式2:
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("线程执行了");
            }
        };
        new Thread(runnable) {
        }.start();
    }
}

7は、タイマーとの使用の概要について
、概要:タイマスレッドツールの非常に広範なアプリケーションであり、複数のタイミングタスクがマナーバックグラウンドスレッドで実行将来のスケジューリングのために使用することができます。Javaでは、スケジュールの定義は機能タイマとTimerTaskをクラスによって実装されてもよいです。
B、タイマーとTimerTaskを

  • タイマー:
    公共タイマー()新しいタイマーを作成//
    ます。public voidスケジュール(TimerTaskをタスク、長い遅延); // スケジュール指定された遅延の後に指定したタスク
    ます。public voidスケジュール(TimerTaskをタスク、長い遅延、長い期間); / /スケジュール繰り返し固定遅延実行するための指定された遅延後に開始されてから指定されたタスク。
    公共のボイドスケジュール(TimerTaskをタスク、日付時刻); // 指定した時刻に指定されたタスクを実行する予定。
    公共のボイドスケジュール(TimerTaskをタスク、日付 FIRSTTIME、長い期間); // 指定された時間固定遅延実行で繰り返し指定されたタスクスケジュール。
  • TimerTaskを
    公共の抽象無効RUN(); //操作は、このタイマータスクによって実行されます。
    パブリックブール()はキャンセル; //このタイマータスクを取り消します。

C、ケースプレゼンテーション

定时任务的多次执行代码体现
定时删除指定的带内容目录
public class MyDemo {
    public static void main(String[] args) throws ParseException {
        Timer timer = new Timer();//创建定时器
        MyTimerTask task = new MyTimerTask(timer);
        //timer.schedule(task,2000); //参数1 定时任务,参数 等待多少毫秒后执行
       // timer.schedule(task,2000,1000);//连环爆炸
        task.cancel(); 取消定时任务
        //指定日期去执行任务
        String dateStr="2019-01-20 13:46:00";
        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
       // timer.schedule(task,date,1000*60*60*24*30);
    }
}
class MyTimerTask extends TimerTask{
    Timer timer;
    public MyTimerTask(Timer timer) {
        this.timer=timer;
    }
    @Override
    public void run() {
       // System.out.println("砰~~~爆炸了");
       // timer.cancel(); //关闭定时器
    }
}
公開された24元の記事 ウォン称賛11 ビュー2049

おすすめ

転載: blog.csdn.net/weixin_43791069/article/details/86684478