javaの情報共有をマルチスレッド

記事では、マルチスレッド知識創造と起動時の問題を紹介し、それぞれの子スレッドと子スレッドまたはサブスレッドとメインスレッドが情報の交換はありませんが、この記事では、スレッドや為替の問題の間で情報の共有に焦点を当てています。この記事では、チケットの例に展開する主です。

スレッドが実行を達成するために継承されたメソッドをオーバーライド


初期コード:

public class Tickect1 {
    public static void main(String[] args) {

        //创建四个线程进行测试
        new Thread3().start();
        new Thread3().start();
        new Thread3().start();
        new Thread3().start();

    }
}

class Thread3 extends Thread{
    private static int tickets = 100;//总票数
    @Override
    public void run() {
        while(true){
            if(tickets<=0){
                break;
            }else{
                System.out.println(Thread.currentThread().getName()+" "+tickets);
                tickets--;
            }
        }
    }
}

誤った回答:103枚のチケットは販売します

理由の分析:1.アトミックオペレーションiが++のような操作ではない


4つのプロセスは、4つの作業キャッシュを有し、データをキャッシュし、各作業が変更されると、4つの作業との間のデータがキャッシュを共有することができない、キャッシュ1が反転されています1チケット、チケット、バッファ2が、キャッシュされたデータが増加するようにチケットを得ることができない、それは103表示
ロック操作の欠如2.キー工程(投票と票の取得動作-1問題が同時に行わ起こります)

改善されたコード:このコードはバグがあり、またはテスト解答103

public class Tickect1 {
    public static void main(String[] args) {

        //创建四个线程进行测试
        new Thread3().start();
        new Thread3().start();
        new Thread3().start();
        new Thread3().start();

    }
}

class Thread3 extends Thread{
    private static volatile int tickets = 100;//总票数
    @Override
    public void run() {
        while(true){
            sale();
            if(tickets<=0) break;
        }
    }

    public synchronized void sale(){//对数据修改进行加锁(同一时刻只能一个线程执行)
        if(tickets>0){
            System.out.println(Thread.currentThread().getName()+" "+tickets);
            tickets--;
        }

    }
}

達成されるのRunnableを達成するために実行する方法

public class Ticket2 {
    public static void main(String[] args) {
        Thread4 t = new Thread4();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();

    }
}


class Thread4 implements Runnable{

    private volatile int tickets=100;//volatile起到通知各个线程缓存区的数据是否修改,如果修改就刷新缓冲区数据(变量副本的解决方法)
    String str = new String("");//对这个对象加锁
    @Override
    public void run() {
        while (true){
           //sale();方式1
            synchronized (str){//代码快加锁(方式2)
                if(tickets>0){
                    System.out.println(Thread.currentThread().getName()+" "+tickets);
                    tickets--;
                }
            }
          if(tickets<=0) break;
        }
    }
    public synchronized void sale(){//synchronized对数据修改进行加锁(同一时刻只能一个线程执行)
        if(tickets>0){//必须在这里判断,if放在外面会出现错误
            System.out.println(Thread.currentThread().getName()+" "+tickets);
            tickets--;
        }

    }
}


volatileキーワードテスト

public class ThreadDemo2
{
    public static void main(String args[]) throws Exception 
    {
        TestThread2 t = new TestThread2();
        t.start();
        Thread.sleep(2000);
        t.flag = false;
        System.out.println("main thread is exiting");
    }
}

class TestThread2 extends Thread
{
    //boolean flag = true;   //子线程不会停止
    volatile boolean flag = true;  //用volatile修饰的变量可以及时在各线程里面通知
    public void run() 
    {
        int i=0;
        while(flag)
        {
            i++;            
        }
        System.out.println("test thread3 is exiting");
    }   
} 

おすすめ

転載: www.cnblogs.com/cstdio1/p/12236400.html