对多线程的理解(1)

最近摸索了一下多线程,记录下心得缓存

1.安全

package com.chenzheng.cn.demo.contorller;多线程

/**
 * 演示出线程的缓存问题
 * 1.若是两个线程同时操做同一个变量
 * 2.则cpu会把这个变量的副本放入缓存中
 * 3.等到cpu运行结束以后,才会把这个缓存返回出来
 * 4.若是不限制主线程,那么主线程打印出来的结果就是最开始的数据
 * @author Administrator
 *
 */
public class ThreadCache 
{
    //1.申明一个变量,供其余线程调用
    private static int a = 0;
    public static void main(String[] args) {
        
        //2.启动两个线程,均完成变量+1操做
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("进入线程1时,a的值 = "+a);
                a++;
            }
        });
        
        Thread thread2 = new Thread(new Runnable() {
            
            @Override
            public void run() {
                System.out.println("进入线程2时,a的值 = "+a);
                a++;
            }
        });
        
        thread1.start();
        thread2.start();
        System.out.println("主线程中,a的值="+a);
    }
}
//最后打印出的结果为:
//进入线程1时,a的值 = 0
//进入线程2时,a的值 = 0
//主线程中,a的值=0
//由此能够看出,a的数据出现了错误ide

 

2.this

package com.chenzheng.cn.demo.contorller;.net

/**
 * 1.为了让主线程可以等待子线程运行完以后再来取到具体的值
 * 2.第一个想到的方法就是让主线程中止一段时间
 * @author Administrator
 *
 */
public class ThreadCache1
{
        //1.申明一个变量,供其余线程调用
        private static int a = 0;
        public static void main(String[] args) {
            
            //2.启动两个线程,均完成变量+1操做
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("进入线程1时,a的值 = "+a);
                    a++;
                    System.out.println("退出线程1是,a的值 = "+a);
                }
            });
            
            Thread thread2 = new Thread(new Runnable() {
                
                @Override
                public void run() {
                    System.out.println("进入线程2时,a的值 = "+a);
                    a++;
                    System.out.println("退出线程2时,a的值 = "+a);
                }
            });
            
            try {
                thread1.start();
                thread2.start();
                Thread.sleep(100);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("主线程中,a的值="+a);
        }
}线程

//进入线程2时,a的值 = 0
//退出线程2时,a的值 = 1
//进入线程1时,a的值 = 0
//退出线程1是,a的值 = 2
//主线程中,a的值=2
//从这里能够看出,静态的共享数据,在进入线程的时候的数据都是0
//而在线程1开始执行新增操做的时候,共享数据已经发生了改变,直接被改变成了2
//最后的返回结果则为2
//不过这样处理就会出现另外的问题,咱们不知道线程里逻辑的复杂程度,若是定了主线程休息100毫秒,
//子线程运行完了或者没有运行完,都会影响系统的效率或则数据安全
//所以须要一个通知,但愿线程在执行完以后可以主动的告诉主线程我完成了任务get

 

 

3.it

package com.chenzheng.cn.demo.contorller;io

public class ThreadCache2 
{
            //1.申明一个变量,供其余线程调用
            private static int a = 0;
            public static void main(String[] args) {
                
                //2.启动两个线程,均完成变量+1操做
                Thread thread1 = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("进入线程1时,a的值 = "+a);
                        a++;
                        System.out.println("退出线程1是,a的值 = "+a);
                    }
                });
                
                Thread thread2 = new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        System.out.println("进入线程2时,a的值 = "+a);
                        a++;
                        System.out.println("退出线程2时,a的值 = "+a);
                    }
                });
                
                try {
                    thread1.start();
                    thread2.start();
                    //在这个方法前面的过后,两个线程都是启动着的,在这个方法后面经过join方法阻塞了主线程,使得主线程只能等待子线程
                    //完成以后才能接着执行下去
                    thread1.join();
                    thread2.join();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("主线程中,a的值="+a);
            }
}

//这样就实现了主线程在子线程执行完以后再执行的目的
//若是咱们想要确保子线程之间的关联关系要怎么办呢,就是线程之间的通信


//假设一个场景,,如今线程一是供货商 suppier , 另一个线程则是收货放销售方 customer
//那么只有供货商提供了货物以后,收货方才有机会能获得货物才能够售货出去
 

 

4.

package com.chenzheng.cn.demo.contorller;

public class ThreadCache31 extends Thread
{
    private Object lock;
    
    public ThreadCache31(Object lock) 
    {
        this.lock = lock;
    }
    
    public void run() 
    {
        while(true) 
        {
            synchronized (lock) {
                if(ThreadCache3Test.shoppingList.isEmpty()) 
                {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                else {
                    System.out.println("取出货物" + ThreadCache3Test.shoppingList.get(0));
                    
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

package com.chenzheng.cn.demo.contorller;

public class ThreadCache32 extends Thread {     private Object lock;          private int index = 0;          public ThreadCache32(Object lock)      {         this.lock = lock;     }          public void run()      {         while(true)          {             synchronized (lock)              {                 ThreadCache3Test.shoppingList.add(index+"");                 System.out.println("放入的货物为"+ index);                 index ++ ;                 lock.notifyAll();                 try {                     Thread.sleep(1000);                 } catch (InterruptedException e) {                     // TODO Auto-generated catch block                     e.printStackTrace();                 }             }         }     } }

相关文章
相关标签/搜索