線程鎖與多線程

(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);
        }
    }

}
發佈了0 篇原創文章 · 獲贊 7 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章