最近摸索了一下多線程,記錄下心得緩存
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(); } } } } }