美文网首页
线程和锁(一)

线程和锁(一)

作者: Cocoonshu粽子 | 来源:发表于2017-06-12 22:44 被阅读27次

    互斥和内存模型

    互斥是啥?互斥是用锁保证某一时间仅有一个线程可以访问数据。

    创建线程
    public class ThreadDemo {
        public static void main(String args[]) throws InterruptedException {
            Thread thread = new Thread(){
                @Override
                public void run() {
                   System.out.println("Hello new thread !");
                }
            };
            thread.start();
            //通知调度器:当前线程想要让出对处理器的占用。
            Thread.yield();
            //Thread.sleep();
            System.out.println("Hello main thread !");
            thread.join();
        }
    }
    

    上面程序运用的结果有两种情况:

    Hello new thread !
    Hello main thread !
    或者
    Hello main thread !
    Hello new thread !
    

    Thread.yield()和Thread.sleep(long millis)区别
    Thread.yield()是暂停当前正在执行的线程对象,并执行其他线程(这里的线程包括当前线程),也就是说虽然暂停了当前线程,下一个时间片仍然可能执行刚刚暂停的线程;
    Thread.sleep(long millis) 是暂停当前线程millis所指定的毫秒,转到执行其他线程;

    第一把锁

    当多个线程共享一块内存时,会导致读写内存数据混乱,为了解决这样的混乱,我们可以用锁达到线程互斥的目的,即同一时间至多有一个线程持有锁。

    public class Counting {
        public static void main(String args[]) throws InterruptedException {
            class Counter{
                private int count = 0;
                public void increment(){
                    ++count;
                }
                public int getCount(){
                    return count;
                }
            }
    
            final Counter counter = new Counter();
    
            class CountingThread extends Thread{
                @Override
                public void run() {
                    for (int i =0;i<10000;++i){
                        counter.increment();
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
    
            CountingThread countingThreadOne = new CountingThread();
            CountingThread countingThreadTwo = new CountingThread();
    
            countingThreadOne.start();
            countingThreadTwo.start();
            countingThreadOne.join();
            countingThreadTwo.join();
    
            System.out.println("Count value:"+counter.getCount());
        }
    }
    
    

    我们会认为结果是20000,但是真的是20000吗?,运用之后显示出乎预料,为什么会出现不是20000的问题呢,问题就出在++count 上,++count 并不是原子操作;
    原子操作:所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。

    相关文章

      网友评论

          本文标题:线程和锁(一)

          本文链接:https://www.haomeiwen.com/subject/qnnlqxtx.html