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