线程和锁(一)

2017-06-12  本文已影响27人  Cocoonshu粽子

互斥和内存模型

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

创建线程
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 (切换到另一个线程)。

上一篇下一篇

猜你喜欢

热点阅读