詳細なJavaベースのマルチスレッド

 

Javaマルチスレッドはプリエンプティブです。優先度が最も高い人が最初に実行します。

Javaはjava.lang.Threadクラスを使用してスレッドを表し、すべてのスレッドオブジェクトはThreadクラスまたはそのサブクラスのインスタンスである必要があります。

スレッドクラス

工法:  

public Thread():新しいスレッドオブジェクトを割り当てます。

public Thread(String name):指定された名前で新しいスレッドオブジェクトを割り当てます。

public Thread(Runnable target):指定されたターゲットに新しいスレッドオブジェクトを割り当てます。

public Thread(Runnable target、String name):指定されたターゲットに新しいスレッドオブジェクトを割り当て、名前を指定します。

一般的な方法:

public String getName():現在のスレッド名を取得します。

public void start():このスレッドに実行を開始させます。Java仮想マシンはこのスレッドのrunメソッドを呼び出します。

public void run():このスレッドによって実行されるタスクはここで定義されます。

public static void sleep(long millis):現在実行中のスレッドを指定されたミリ秒数の間一時停止します(実行を一時的に停止します)。

public static Thread currentThread():現在実行中のスレッドオブジェクトへの参照を返します。

public void Join()はスレッドを終了します

マルチスレッドを作成して開始する手順

1つは、基本クラスThreadを使用する

1. Threadクラスのサブクラスを定義し、このクラスのrun()メソッドを書き直します。run()メソッドのメソッド本体は、スレッドが完了する必要のあるタスクを表すため、run()メソッドはスレッド実行と呼ばれます。体。

2. Threadサブクラスのインスタンスを作成します。つまり、スレッドオブジェクトを作成します。

3.スレッドオブジェクトのstart()メソッドを呼び出して、スレッドを開始します

public class MyThread extends Thread{
	@Override
	public void run() {
		for( int i = 0;i < 20;i++){
			System.out.println("run"+i);
		}
	}
}
public static void main (String[]args){
	//多线程
	MyThread my1 = new MyThread();
	//my1.run();调用run()方法     单线程
	my1.start();//执行run()方法   多线程   新开一个栈空间
	//main执行
	for(int i  = 0;i < 20;i++){
		System.out.println("main"+i);
	}
}

次に、Runnableインターフェイスを使用します

1. Runnableインターフェースの実装クラスを定義し、インターフェースのrun()メソッドを書き直します。run()メソッドのメソッド本体は、スレッドのスレッド実行本体でもあります。

2. Runnable実装クラスのインスタンスを作成し、このインスタンスをThreadターゲットとして使用して、実際のスレッドオブジェクトであるThreadオブジェクトを作成します。

3.スレッドオブジェクトのstart()メソッドを呼び出して、スレッドを開始します

public class DemoRunnableImpl implements Runnable{//步骤一
	@Override
	public void run(){
		for(int i = 0;i < 5;i++){
			System.out.println(Thread.currentThread().getName()+"-->"+i);
		}
	}
}
public static void main (String[] args){
	DemoRunnableImpl demo =new DemoRunnableImpl();//步骤二
	Thread thread= new Thread (demo);
	thread.start();//步骤三
}

第三に、匿名の内部クラスを使用します

public static void main(String[] args){
	//线程的父类是Thread
	new  Thread(){
		@Override
		public void run(){
			for(int i = 0;i < 5;i++){
				System.out.println(Thread.currentThread().getName()+"小小张自由");
			}
		}
	}.start();
	//线程的接口是Runnable
	Runnable r = new Runnable(){
		@Override
		public void run(){
			for(int i = 0;i < 5;i++){
				System.out.println(Thread.currentThread().getName()+"身体健康");
			}
		}
	};
	new Thread(r).start();
}

スレッドセーフの問題を解決する

スレッドセーフの問題は、グローバル変数と静的変数が原因で発生します。各スレッドにグローバル変数と静的変数に対する読み取り操作のみがあり、操作がない場合、通常、このグローバル変数はスレッドセーフです。

複数のスレッドが同時に書き込み操作を実行する場合は、通常、スレッドの同期を考慮する必要があります。そうしないと、スレッドの安全性に影響が及ぶ可能性があります。

同期キーワードは、メソッド内のブロックで使用できます。つまり、このブロックのリソースに対して相互に排他的なアクセスのみが実行されます。

ロックオブジェクトはどのタイプでもかまいません。複数のスレッドオブジェクトが同じロックを使用します。いつでも、実行中の最大1つのスレッドに同期ロックがあり、ロックを取得した人は誰でもコードブロックに入り、他のスレッドは待機することしかできません。

1つは、同期コードブロックです

//语法格式
synchronized(同步锁){
	//需要同步操作的代码
}
//示例
private int cont = 100;
Object obj = new Object();
@Override
public void run(){
	synchronized(obj){ //被锁住的代码
		while(cont>0){
			//线程休眠10毫秒
			try{
				Thread.sleep(10);
			}catch(Exceptione){
				System.out.println(e.getMessage());
			}
			System.out.println(Thread.currentThread().getName()+"正在抢第"+cont+"票");
			cont--;
		}
	}
}

2、同期方法

同期する必要のあるコードを抽出します。メソッドに入れてください。次に、Run()メソッドは同期メソッドを呼び出します

public synchronized void method(){ 
	//可能会产生线程安全问题的代码 
}

3.ロック機構

     1.メンバーの場所にReentrantLockオブジェクトを作成します

     2.セキュリティ上の問題がある可能性のあるコードの前に、ロックインターフェイスでメソッドLockを呼び出してロックを取得します

     3.セキュリティ上の問題がある可能性のあるコードの後で、LockインターフェイスでメソッドunLockを呼び出して、ロックを解放します

public class DemoRunnableImpl implements Runnable {
    private int cont = 100;
    Lock lock=new ReentrantLock();//创建一个ReentrantLock对象
    @Override
    public void run() {
        lock.lock();//获取锁
        while (cont > 0) {
            //线程休眠10毫秒
            try {
                Thread.sleep(10);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            System.out.println(Thread.currentThread().getName() + "正在抢第" + cont + "票");
            cont--;
        }
        lock.unlock();//释放锁
    }
}

スレッド間の通信

    複数のスレッドを同時に実行する場合、デフォルトのCPUはランダムにスレッドを切り替えます。いずれかのタスクを完了する必要がある場合は複数のスレッドを切り替え、法律を実装する必要があります。非常に多くのスレッドの中で、通信の調整が必要です。データのマルチスレッド協調を実現するのに役立つため。

スレッドステータスの概要

 事件を待って目覚めさせる-生産者と消費者

        1.顧客スレッドとボススレッドは、待機と覚醒の1つだけを実行できるように、同期コードブロックでラップする必要があります。

        2.同期的に使用されるロックオブジェクトは一意である必要があります

        3.ロックオブジェクトのみがwait ()メソッドnotify()メソッドを使用できます

public static void main(String[] args) {
        Object obj=new Object();//锁对象
        //消费者
        new Thread(){
            @Override
            public void run() {
                while (true){
                    synchronized (obj){  //同步代码段
                        System.out.println("告知老板要的包子种类和数量");
                        try {
                            obj.wait();//线程等待
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //唤醒之后执行的代码
                        System.out.println("包子已经做好了,开吃!");
                    }
                }
            }
        }.start();
        //生产者
        new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        Thread.sleep(5000); //花5s做包子
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (obj){ //同步代码段
                        System.out.println("老板5秒钟包子做好了,可以吃包子了!");
                        //做好包子,调用notify方法,唤醒顾客吃包子
                        obj.notify();
                        System.out.println("---------------------");
                    }
                }
            }
        }.start();
    }

 作成は簡単ではありません。このブログがお役に立てば、メッセージを残してください+いいね!

おすすめ

転載: blog.csdn.net/promsing/article/details/112408018