最近摸索了一下多线程,记录下心得缓存
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(); } } } } }