javaAPI 多線程總結

進程:


線程:


進程與線程區別:


線程使用場合:



實現多線程有幾種方法?
三種,

     
                1.繼承Thread類,重寫run函數


                2.實現Runnable接口,重寫run函數


                3.實現Callable接口,重寫call函數




thread:

public class testThread {

	/**
	 * 測試多線程併發
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread t1 = new myThread();
		Thread t2 = new myThread();
		t1.start();
		t2.start();
	}

}
/*
 * 線程
 */
class myThread extends Thread{
	public void run(){
		for(int i = 1; i <= 100; i++){
			System.out.println(i);
		}
	}
}

runnable:

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class testRunnable extends JFrame implements Runnable{
	/**
	 * 測試runnable
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		testRunnable r = new testRunnable();
		r.setSize(300,300);
		r.setVisible(true);
		r.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Thread t = new Thread(r);
		t.start();
	}
	public void run(){
		int i = 0;
		JPanel panel = new JPanel();
		panel.setSize(300,300);
		this.setContentPane(panel);
		while(true){
			i = i == 0? 1:0;
			if(i == 0){
				panel.setBackground(Color.BLACK);
			}else{
				panel.setBackground(Color.YELLOW);
			}
		}
	}
}

使用匿名內部類創建線程:

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class testInnerThread {

	/**
	 * 使用匿名內部類方式創建線程
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame frame = new JFrame();
		frame.setSize(300,300);
		final JPanel panel = new JPanel() ;
		panel.setSize(300,300);
		frame.setContentPane(panel);
		frame.setVisible(true);
		Thread t = new Thread(){
			public void run(){
				int i = 0;
				while(true){
					i = i == 0?1:0;
					if(i == 0){
						panel.setBackground(Color.BLACK);
					}else{
						panel.setBackground(Color.WHITE);
					}
				}						
			}
		};
		t.start();
	}

}

一道面試題:

Sleep()和wait()有什麼區別?
             sleep是線程類(Thread)的方法,導致此線程暫停執行指定時間,把執行機會給其他線程,但是監控狀態依然保持,到時後會自動恢復。調用sleep不會釋放對象鎖。


             wait().會釋放鎖


currentThread:

public class testCurrentThread {

	/**
	 * 測試currentThread方法
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("運行main方法的線程是" + Thread.currentThread());
		testCurrent();
		Thread t = new Thread(){
			public void run(){
				System.out.println("線程t" + Thread.currentThread());
				testCurrent();
			}
		};
		t.start();
	}
	/**
	 * 測試不同線程調用該方法時,獲取這個線程
	 */
	public static  void testCurrent(){
		System.out.println("運行testcurrent方法的線程是" + Thread.currentThread());
	}
}


獲取線程名字及id:

/**
 * 獲取線程名字及id
 */
public class testThreadNameAndId {

	/**
	 * 測試getName及getId
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread t = new Thread();
		System.out.println(t.getName());
		System.out.println(t.getId());
		Thread t1 = new Thread();
		System.out.println(t1.getName());
		System.out.println(t1.getId());
		//爲線程自定義名字
		Thread t2 = new Thread("黃色潛水艇");
		System.out.println(t2.getName());
		System.out.println(t2.getId());
	}

}



守護線程:

public class testDaemonThread {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread d = new Thread(){
			public void run(){
				while(true){
					System.out.println("後臺線程");
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		d.setDaemon(true);
		d.start();
		try {
			//使main線程阻塞五秒
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//進程中所有前臺線程結束後,後臺線程制結束
		System.out.println("main線程結束了");
	}

}

線程等待join():

public class testJoin {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final Thread t1 = new Thread(){
			public void run(){
				for(int i = 0; i <= 10; i++){
					System.out.println("t1:正在下載圖片:"  + i*10  + "%");
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				System.out.println("t1:圖片下載完畢");
			}
		};
		Thread t2 = new Thread(){
			public void run(){
				System.out.println("等待t1");
				try {
					t1.join();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("t2顯示圖片");
			}
		};
		
		t1.start();
		t2.start();
	}

}


synchronized:                                                                     鎖機制:



兩個線程互斥,synchronized(String string),則string相同。


線程安全與非線程安全:



線程池:



import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 測試線程池
 * @author wangyu
 *
 */
public class testExecutorService {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//線程池每次啓動兩個線程來執行任務,由於要求執行五次任務,所以
		//線程池要求分三次執行。
		ExecutorService threadPool = Executors.newFixedThreadPool(2);
		for(int i = 0; i < 5; i++){
			Handler handler = new Handler();
			threadPool.execute(handler);
		}
	}

}
class Handler implements Runnable{
	public void run(){
		String name = Thread.currentThread().getName();
		System.out.println("正在執行的線程" + name);
		for(int i = 0; i < 10; i++){
			System.out.println(name + ":" + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(name + "任務完成");
	}
}



雙緩衝隊列:




import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 測試雙緩衝隊列
 * (1)首先,使用ArrayBlockingQueue類創建一個大小爲10的雙緩衝隊列
 * queue;然後,循環20次向隊列queue中添加元素,如果5秒內元素仍沒有入隊
 * 到隊列中,則返回false。
 * (2)首先,使用ArrayBlockingQueue類創建一個大小爲10的雙緩衝隊列
 * queue;然後,將0到9,10個數字加入到隊列queue中;最後,循環20次從
 * 隊列queue中取元素,如果5秒內元素仍沒有入隊,則返回null。
 * @author wangyu
 */
public class testBlockingQueue {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		testBlockingQueue tbq = new testBlockingQueue();
//		tbq.testOffer();
		tbq.testPull();
	}
	/**
	 * 測試入隊方法
	 */
	public void testOffer(){
		BlockingQueue <Integer> queue = new ArrayBlockingQueue<Integer>(10);
		for(int i = 0; i < 20; i++){
			try {
				  boolean b = queue.offer(i,5,TimeUnit.SECONDS);
				  System.out.println("存入是否成功" + b);
			  } catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	/**
	 * 測試出隊方法
	 */
	public void testPull(){
		BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10);
		for(int i = 0; i < 20; i++){
			queue.offer(i);
		}
		for(int i = 0;i < 20; i++){
			//獲取元素,設置5秒超時,5秒內還沒有元素可取回則返回null			
			try {
				Integer num= queue.poll(5, TimeUnit.SECONDS);
				System.out.println("元素" + num);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}			
		}
	}
}


面試題:


子線程循環10次,接着主線程循環100,接着又子線程循環10次,接着又主線程循環100,如此50次。寫出代碼:

/** 
 * 子線程循環10次,接着主線程循環100,接着又回到子線程循環10次,接着再回到主線程又循環100,如此循環50次,請寫出程序。 
 * @author lijinnan 
 * @date:2013-11-5 下午3:07:10   
 */  
public class ThreadComunication {  
  
    private static final int ROUND_COUNT = 50;  
      
    public static void main(String[] args) {  
          
        //主線程和子線程“共享”一個Busines實例  
        final Business business = new Business();  
          
        /* 
        //主線程 
        for (int i = 0; i < ROUND_COUNT; i++) { 
            business.main(i); 
        } 
        */  
          
        //子線程-注意要先啓動子線程,否則子線程不會啓動,主線程在roundIndex=0執行完畢後就陷入無限等待  
        new Thread(new Runnable() {  
              
            @Override  
            public void run() {  
                for (int i = 0; i < ROUND_COUNT; i++) {  
                    business.sub(i);  
                }  
            }  
              
        }).start();  
          
        //主線程  
        for (int i = 0; i < ROUND_COUNT; i++) {  
            business.main(i);  
        }  
    }  
  
}  
  
  
class Business {  
      
    private static final int SUB_COUNT = 10;  
    private static final int MAIN_COUNT = 100;  
      
    private boolean doSub;  
      
    public synchronized void sub(int roundIndex) {  
        while (!doSub) {  
            try {  
                wait();  
            } catch (InterruptedException e) {  
                //ignore  
            }  
        }   
        for (int i = 0; i < SUB_COUNT; i++) {  
            System.out.println("sub " + i + " of " + roundIndex);  
        }  
        doSub = false;  
        notifyAll();  
    }  
      
    public synchronized void main(int roundIndex) {  
        while (doSub) {  
            try {  
                wait();  
            } catch (InterruptedException e) {  
                //ignore  
            }  
        }   
        for (int i = 0; i < MAIN_COUNT; i++) {  
            System.out.println("main " + i + " of " + roundIndex);  
        }  
        doSub = true;  
        notifyAll();  
    }  
      
}  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章