(1)
package day20150914sync;
/**
* 線程併發安全問題
*/
public class SyncDemo1 {
//桌子上有20個豆子
public static int beans = 20;
public static void main(String[] args) {
Thread t1 = new Thread(){
public void run(){
int bean = 0;
while(true){
bean = getBean();
Thread.yield();//讓線程延遲
System.out.println(this.getName()+":"+bean);
}
}
};
Thread t2 = new Thread(){
public void run(){
int bean = 0;
while(true){
bean = getBean();
Thread.yield();//讓線程延遲
System.out.println(this.getName()+":"+bean);
}
}
};
t1.start();
t2.start();
}
/**
* synchronized:加鎖之後,
* 單個線程徹底運行完方法後才釋放鎖
* 方法鎖的對象是this
*/
public synchronized static int getBean(){
if(beans==0){
throw new RuntimeException("沒豆子了");
}
try {
Thread.sleep(50);//sleep50毫秒
} catch (InterruptedException e){
e.printStackTrace();
}
return beans--;
}
}
/*
* 備註:
* StringBuffer:線程安全
* StringBuilder:線程不安全
*
* 例如append的時候
*/
(2)
package day20150914sync;
/**
* 有效減少同步範圍可提高效率
*
*/
public class SyncDemo2 {
private static Object obj = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(){
public void run(){
buy(this.getName());//靜態方法不用點“.”
}
};
Thread t2 = new Thread(){
public void run(){
buy(this.getName());
}
};
t1.start();
t2.start();
}
//鎖住整個方法,類作爲鎖,當前線程完全執行完方法後,其他線程纔可使用此方法
//public static synchronized void buy(String name){
public static void buy(String name){
System.out.println(name+"挑衣服");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//多個線程看到的是同一個對象,才具有同步效力
/*
* 如果synchronized塊在某一個非靜態方法中,
* 那麼通常鎖對象寫的是this
*
* 靜態方法中不能使用非靜態對象
*/
synchronized (obj) {
System.out.println(name + "開始試衣服。。。");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "試衣服結束。。。");
}
System.out.println(name+"結賬");
}
}
(3)
package day20150914sync;
/**
* 有效減少同步範圍可提高效率(非靜態方法)
*/
public class SyncDemo3 {
public static void main(String[] args) {
//匿名內部類使用demo,需要是final
final SyncDemo3 demo = new SyncDemo3();
Thread t1 = new Thread(){
public void run(){
demo.buy(this.getName());//匿名內部類使用demo,需要是final
}
};
Thread t2 = new Thread(){
public void run(){
demo.buy(this.getName());
}
};
t1.start();
t2.start();
}
/**非靜態方法
*/
public void buy(String name){
System.out.println(name+"挑衣服");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//多個線程看到的是同一個對象,才具有同步效力
/*
* 如果synchronized塊在某一個非靜態方法中,
* 那麼通常鎖對象寫的是this
*
* 靜態方法中不能使用非靜態對象
*/
synchronized (this) {
System.out.println(name + "開始試衣服。。。");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "試衣服結束。。。");
}
System.out.println(name+"結賬");
}
}
(4)
package day20150914sync;
public class ThreadDemo4join {
/**
* 圖片是否下載完
*/
public static boolean isFinish;
public static void main(String[] args) {
final Thread download = new Thread(){
public void run(){
/*
* 下載圖片
*/
System.out.println("開始下載圖片。。。");
for(int i=1;i<=10;i++){
System.out.println(i+"0%");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("圖片下載完成");
isFinish = true;
/*
* 下載附件
*/
System.out.println("開始下載附件");
for(int i=1;i<=10;i++){
System.out.println(i+"0%");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("附件下載完成");
}
};
/**
* 顯示圖片
*
* main方法中定義了一個內部類show
* 該內部類中若想引用main方法中的其他局部變量
* 那麼這個變量必須是final的
*/
Thread show = new Thread(){
public void run(){
//這裏等待圖片下載完成
try {
download.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("開始顯示圖片");
if(!isFinish){
throw new RuntimeException("圖片還沒有下載完成");
}
System.out.println("圖片打開");
}
};
download.start();
show.start();
}
}
(5)
package day20150914sync;
public class ThreadDemo5waitnotify {
/**
* 圖片是否下載完
*/
private static boolean isFinish;
private static final Object obj = new Object();
public static void main(String[] args) {
final Thread download = new Thread(){
public void run(){
/*
* 下載圖片
*/
System.out.println("開始下載圖片。。。");
for(int i=1;i<=10;i++){
System.out.println(i+"0%");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("圖片下載完成");
isFinish = true;
synchronized(obj){
/*
* 圖片下完,就當通知去顯示圖片
* notify()需要加鎖
* notify()只會隨機基礎一個在當前對象等待的線程
* notifyAll()全解除
*
* 調用哪個對象的wait或notify,就應當對當前方法加鎖
* 鎖對象就是當前對象
*/
obj.notify();//notifyAll():全部解除在等待的所有線程
}
/*
* 下載附件
*/
System.out.println("開始下載附件");
for(int i=1;i<=10;i++){
System.out.println(i+"0%");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("附件下載完成");
}
};
/**
* 顯示圖片
*
* main方法中定義了一個內部類show
* 該內部類中若想引用main方法中的其他局部變量
* 那麼這個變量必須是final的
*/
Thread show = new Thread(){
public void run(){
//這裏等待圖片下載完成
try {
//download.join();
synchronized(obj){
//在obj對象上等待,要加鎖
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("開始顯示圖片");
if(!isFinish){
throw new RuntimeException("圖片還沒有下載完");
}
System.out.println("圖片打開");
}
};
download.start();
show.start();
}
}
(6)
package day20150914sync;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CollectionsSynchronized6 {
/**
* 將集合或Map轉爲線程安全的
*/
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
//將List集合轉爲線程安全的
list = Collections.synchronizedList(list);
System.out.println(list);
//將Set集合轉爲線程安全的
Set<String> set = new HashSet<String>();
set = Collections.synchronizedSet(set);
//將Map轉爲線程安全的
Map<String, Integer> map = new HashMap<String, Integer>();
map = Collections.synchronizedMap(map);
}
}
(7)
package day20150914sync;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 線程池:
* 1:控制線程數量
* 2:重用線程
*/
public class ThreadPool7 {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(2);
for(int i=0;i<5;i++){
Runnable runn = new Runnable(){
@Override
public void run() {
for(int i=0;i<4;i++){
System.out.println(i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
//Thread t = new Thread(runn);
//t.start();
threadPool.execute(runn);
}
}
}