java multithreading information sharing

The article introduces the multithreading knowledge creation and startup problems, each child thread and the child thread or sub-thread and main thread is not the exchange of information, this article focuses on information sharing between threads and exchange issues. This article is mainly to expand to a ticket example.

Thread override the inherited method to achieve run


Initial Code:

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--;
            }
        }
    }
}

Incorrect Answers: 103 tickets sold

Analysis of reasons: 1. The operation is not like i ++ atomic operations


four process has four working cache, each work cached data is modified, and data between the four work can not be shared cache, cache 1 has been inverted 1-tickets, tickets and the buffer 2 but can not obtain a ticket so that the cached data increases, it appears 103
2. the key step of the lack of lock operation (acquisition operation of the votes and votes -1 problems occur simultaneously performed)

Improved code: This code has a bug, or test answers 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--;
        }

    }
}

run way to achieve Runnable be achieved

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 keyword test

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");
    }   
} 

Guess you like

Origin www.cnblogs.com/cstdio1/p/12236400.html