201771010134楊其菊《面向物件程式設計(java)》第十六週學習總結
第十六週學習總結
第一部分:理論知識
1. 程式是一段靜態的程式碼,它是應用程式執行的藍本。程序是程式的一次動態執行,它對應了從程式碼載入、執行至執行完畢的一個完整過程。作業系統為每個程序分配一段獨立的記憶體空間和系統資源,包括:程式碼資料以及堆疊等資源。每一個程序的內部資料和狀態都是完全獨立的。多工作業系統中,程序切換對CPU資源消耗較大。
2. 多執行緒是程序執行過程中產生的多條執行線索。執行緒是比程序執行更小的單位。執行緒不能獨立存在,必須存在於程序中,同一程序的各執行緒間共享程序空間的資料。每個執行緒有它自身的產生、存在和消亡的過程,是一個動態的概念。多執行緒意味著一個程式的多行語句可以看上去幾乎在同一時間內同時執行。執行緒建立、銷燬和切換的負荷遠小於程序,又稱為輕量級程序。
3. Java實現多執行緒有兩種途徑:建立Thread類的子類;在程式中定義實現Runnable介面的類。
4. 用Thread類的子類建立執行緒:首先需從Thread類派生出一個子類,在該子類中重寫run()方法。然後用建立該子類的物件Lefthand left=new Lefthand(); Righthand right=new Righthand();最後用start()方法啟動執行緒 left.start(); right.start();
5. 用Thread類的子類建立多執行緒的關鍵性操作:定義Thread類的子類並實現使用者執行緒操作,即run()方法的實現。在適當的時候啟動執行緒。由於Java只支援單重繼承,用這種方法定義的類不可再繼承其他父類。
6.用Runnable()介面實現執行緒:首先設計一個實現Runnable介面的類;然後在類中根據需要重寫run方法;再建立該類物件,以此物件為引數建立Thread 類的物件;呼叫Thread類物件的start方法啟動執行緒,將 CPU執行權轉交到run方法。
7.Thread(Runnable r):建立一個新執行緒,它呼叫r的run(), r是一個實現了Runnable介面的類的例項。
8.執行緒兩種建立方法比較:實現Runnable介面的優勢:符合OO設計的思想;便於用extends繼承其它類。採用繼承Thread類方法的優點:程式碼簡單。
9. 執行緒的終止:當執行緒的run方法執行方法體中最後一條語句後,或者出現了在run方法中沒有捕獲的異常時,執行緒將終止,讓出CPU使用權。呼叫interrupt()方法也可終止執行緒。 void interrupt() :向一個執行緒傳送一箇中斷請求,同時把這個執行緒的“interrupted”狀態置為true。若該執行緒處於 blocked 狀 態,會丟擲 InterruptedException。
10. 測試執行緒是否被中斷的方法:static boolean interrupted() :檢測當前執行緒是否已被中斷,並重置狀態 “interrupted”值為false。 boolean isInterrupted() :檢測當前執行緒是否已被中斷 , 不改變狀態 “interrupted”值 利用各執行緒的狀態變換,可以控制各個執行緒輪流 使用CPU,體現多執行緒的並行性特徵。
11. 執行緒有如下7種狀態:New (新建);Runnable (可執行);Running(執行) ;Blocked (被阻塞) ;Waiting (等待) ;Timed waiting (計時等待) ; Terminated (被終止)。
new(新建):執行緒物件剛剛建立,還沒有啟動,此時執行緒還處於不可執行狀態。例如: Thread thread=new Thread(r); 此時執行緒thread處於新建狀態,有了相應的記憶體空間以及其它資源。
runnable(可執行狀態):此時執行緒已經啟動,處於執行緒的run()方法之中。此時的執行緒可能執行,也可能不執行,只要 CPU一空閒,馬上就會執行。呼叫執行緒的start()方法可使執行緒處於“可執行”狀態。例如: thread.start();
12. blocked (被阻塞):一個正在執行的執行緒因特殊原因,被暫停執行,進入阻塞狀態。阻塞時執行緒不能進入佇列排隊,必須等到引起阻塞的原因消除,才可重新進入排隊佇列。引起阻塞的原因很多,不同原因要用不同的方法解除。sleep(),wait()是兩個常用引起執行緒阻塞的方法。
13. 執行緒阻塞的三種情況:等待阻塞:通過呼叫執行緒的wait()方法,讓執行緒等待某工作的完成。同步阻塞:執行緒在獲取synchronized同步鎖失敗(因為鎖被其它執行緒所佔用),它會進入同步阻 塞狀態。 其他阻塞:通過呼叫執行緒的sleep()或join() 或發出了I/O請求時,執行緒會進入到阻塞狀態。當 sleep()狀態超時、join()等待執行緒終止或者超時、或者I/O處理完畢時,執行緒重新轉入就緒狀態。
14. Terminated (被終止) :執行緒被終止的原因有二:一是run()方法中最後一個語句執行完畢而自 然死亡。二是因為一個沒有捕獲的異常終止了run方法而意外死亡。可以呼叫執行緒的 stop 方法殺死一個執行緒(thread.stop();),但是,stop方法已過時,不要在自己的程式碼中呼叫它。
15. Java 的執行緒排程採用優先順序策略:優先順序高的先執行,優先順序低的後執行;多執行緒系統會自動為每個執行緒分配一個優先順序,預設時,繼承其父類的優先順序; 任務緊急的執行緒,其優先順序較高; 同優先順序的執行緒按“先進先出”的佇列原則。
16.Thread類有三個與執行緒優先順序有關的靜態量: MAX_PRIORITY:最大優先權,值為10; MIN_PRIORITY:最小優先權,值為1; NORM _PRIORITY:預設優先權,值為5。
呼叫setPriority(int a)重置當前執行緒的優先順序,a取值可以是前述的三個靜態量。呼叫getPriority()獲得當前執行緒優先順序。
17.下面幾種情況下,當前執行執行緒會放棄CPU:執行緒呼叫了yield() 或sleep() 方法;搶先式系統下,有高優先順序的執行緒參與排程;由於當前執行緒進行I/O訪問、外存讀寫、等待用 戶輸入等操作導致執行緒阻塞;或者是為等候一個條件變數,以及執行緒呼叫wait() 方法。
18.守護執行緒的惟一用途是為其他執行緒提供服務。例如計時執行緒。在一個執行緒啟動之前,呼叫setDaemon方法可將執行緒轉換為守護執行緒。例如:setDaemon(true);
19.多執行緒併發執行中的問題:多個執行緒相對執行的順序是不確定的。執行緒執行順序的不確定性會產生執行結果的不確定性。在多執行緒對共享資料操作時常常會產生這種不確定性
2.多執行緒併發執行不確定性問題解決方案:引入執行緒同步機制,使得另一執行緒要使用該方法,就只能等待。
21. 在Java中解決多執行緒同步問題的方法有兩種:J ava SE 5.0中引入ReentrantLock類。 在共享記憶體的類方法前加synchronized修飾符。
22.有關鎖物件和條件物件的關鍵要點:鎖用來保護程式碼片段,保證任何時刻只能有一個執行緒執行被保護的程式碼。鎖管理試圖進入被保護程式碼段的執行緒。鎖可擁有一個或多個相關條件物件。每個條件物件管理那些已經進入被保護的程式碼 段但還不能執行的執行緒。
23.synchronized關鍵字作用: 某個類內方法用synchronized 修飾後,該方法被稱為同步方法;只要某個執行緒正在訪問同步方法,其他執行緒欲要訪問同步方法就被阻塞,直至執行緒從同 步方法返回前喚醒被阻塞執行緒,其他執行緒方可能進入同步方法。
24.在同步方法中使用wait()、notify 和notifyAll()方法:一個執行緒在使用的同步方法中時,可能根據問題的需要,必須使用wait()方法使本執行緒等待,暫時讓出CPU的使用權,並允許其它執行緒使用這個同步方法。執行緒如果用完同步方法,應當執行notifyAll()方 法通知所有由於使用這個同步方法而處於等待的 執行緒結束等待
第二部分:實驗
實驗十六 執行緒技術
實驗時間 2017-12-8
1、實驗目的與要求
(1) 掌握執行緒概念;
(2) 掌握執行緒建立的兩種技術;
(3) 理解和掌握執行緒的優先順序屬性及排程方法;
(4) 掌握執行緒同步的概念及實現技術;
2、實驗內容和步驟
實驗1:測試程式並進行程式碼註釋。
測試程式1:
l 在elipse IDE中除錯執行ThreadTest,結合程式執行結果理解程式;
l 掌握執行緒概念;
l 掌握用Thread的擴充套件類實現執行緒的方法;
l 利用Runnable介面改造程式,掌握用Runnable介面建立執行緒的方法。
1 class Lefthand extends Thread { 2 public void run() 3 { 4 for(int i=0;i<=5;i++) 5 { System.out.println("You are Students!"); 6 try{ sleep(500); } 7 catch(InterruptedException e) 8 { System.out.println("Lefthand error.");} 9 } 10 } 11 } 12 class Righthand extends Thread { 13 public void run() 14 { 15 for(int i=0;i<=5;i++) 16 { System.out.println("I am a Teacher!"); 17 try{ sleep(300); } 18 catch(InterruptedException e) 19 { System.out.println("Righthand error.");} 20 } 21 } 22 } 23 public class ThreadTest 24 { 25 static Lefthand left; 26 static Righthand right; 27 public static void main(String[] args) 28 { left=new Lefthand(); 29 right=new Righthand(); 30 left.start(); 31 right.start(); 32 } 33 }
利用Runnable介面改造程式修改後
1 class Lefthand implements Runnable { 2 public void run() { 3 for (int i = 0; i <= 5; i++) { 4 System.out.println("You are Students!"); 5 try { 6 Thread.sleep(500); 7 } catch (InterruptedException e) { 8 System.out.println("Lefthand error."); 9 } 10 } 11 } 12 } 13 14 class Righthand implements Runnable { 15 public void run() { 16 for (int i = 0; i <= 5; i++) { 17 System.out.println("I am a Teacher!"); 18 try { 19 Thread.sleep(300); 20 } catch (InterruptedException e) { 21 System.out.println("Righthand error."); 22 } 23 } 24 } 25 } 26 27 public class ThreadTest { 28 public static void main(String[] args) { 29 Runnable left = new Lefthand(); 30 Thread a = new Thread(left); 31 Runnable right = new Righthand(); 32 Thread b = new Thread(right); 33 a.start(); 34 b.start(); 35 } 36 }ThreadTest
測試程式2:
l 在Elipse環境下除錯教材625頁程式14-1、14-2 、14-3,結合程式執行結果理解程式;
l 在Elipse環境下除錯教材631頁程式14-4,結合程式執行結果理解程式;
l 對比兩個程式,理解執行緒的概念和用途;
l 掌握執行緒建立的兩種技術。
(1) 在Elipse環境下除錯教材625頁程式14-1、14-2 、14-3,結合程式執行結果理解程式;
1 package bounceThread; 2 3 import java.awt.geom.*; 4 5 /** 6 A ball that moves and bounces off the edges of a 7 rectangle 8 * @version 1.33 2007-05-17 9 * @author Cay Horstmann 10 */ 11 public class Ball 12 { 13 private static final int XSIZE = 15; 14 private static final int YSIZE = 15; 15 private double x = 0; 16 private double y = 0; 17 private double dx = 1; 18 private double dy = 1; 19 20 /** 21 Moves the ball to the next position, reversing direction 22 if it hits one of the edges 23 */ 24 //定義了移動方法 25 public void move(Rectangle2D bounds) 26 { 27 x += dx; 28 y += dy; 29 if (x < bounds.getMinX()) 30 { 31 x = bounds.getMinX(); 32 dx = -dx; 33 } 34 if (x + XSIZE >= bounds.getMaxX()) 35 { 36 x = bounds.getMaxX() - XSIZE; 37 dx = -dx; 38 } 39 if (y < bounds.getMinY()) 40 { 41 y = bounds.getMinY(); 42 dy = -dy; 43 } 44 if (y + YSIZE >= bounds.getMaxY()) 45 { 46 y = bounds.getMaxY() - YSIZE; 47 dy = -dy; 48 } 49 } 50 51 /** 52 Gets the shape of the ball at its current position. 53 */ 54 //定義球外形 55 public Ellipse2D getShape() 56 { 57 return new Ellipse2D.Double(x, y, XSIZE, YSIZE); 58 } 59 } 60 61 BallBall
package bounce; import java.awt.*; import java.util.*; import javax.swing.*; /** * The component that draws the balls. * @version 1.34 2012-01-26 * @author Cay Horstmann */ public class BallComponent extends JPanel { private static final int DEFAULT_WIDTH = 450; private static final int DEFAULT_HEIGHT = 350; private java.util.List<Ball> balls = new ArrayList<>(); /** * Add a ball to the component. * @param b the ball to add */ public void add(Ball b) { balls.add(b); } public void paintComponent(Graphics g) { super.paintComponent(g); // erase background Graphics2D g2 = (Graphics2D) g; for (Ball b : balls) { g2.fill(b.getShape()); } } public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } } BallComponentBallComponent
1 package bounce; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * Shows an animated bouncing ball. 9 * @version 1.34 2015-06-21 10 * @author Cay Horstmann 11 */ 12 public class Bounce 13 { 14 public static void main(String[] args) 15 { 16 EventQueue.invokeLater(() -> { 17 JFrame frame = new BounceFrame(); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 } 23 24 /** 25 * The frame with ball component and buttons. 26 */ 27 class BounceFrame extends JFrame 28 { 29 private BallComponent comp; 30 public static final int STEPS = 1000; 31 public static final int DELAY = 3; 32 33 /** 34 * Constructs the frame with the component for showing the bouncing ball and 35 * Start and Close buttons 36 */ 37 public BounceFrame() 38 { 39 setTitle("Bounce"); 40 comp = new BallComponent(); 41 add(comp, BorderLayout.CENTER); 42 JPanel buttonPanel = new JPanel(); 43 addButton(buttonPanel, "Start", event -> addBall());//將按鈕放入buttonPanel 44 addButton(buttonPanel, "Close", event -> System.exit(0)); 45 add(buttonPanel, BorderLayout.SOUTH);//將buttonPanel放入邊界管理器的南端 46 pack(); 47 } 48 49 /** 50 * Adds a button to a container. 51 * @param c the container 52 * @param title the button title 53 * @param listener the action listener for the button 54 */ 55 public void addButton(Container c, String title, ActionListener listener) 56 { 57 //生成按鈕物件 58 JButton button = new JButton(title); 59 c.add(button); 60 button.addActionListener(listener);//註冊監聽器事件 61 } 62 63 /** 64 * Adds a bouncing ball to the panel and makes it bounce 1,000 times. 65 */ 66 public void addBall() 67 { 68 try 69 { 70 Ball ball = new Ball(); 71 comp.add(ball); 72 73 for (int i = 1; i <= STEPS; i++) 74 { 75 ball.move(comp.getBounds()); 76 comp.paint(comp.getGraphics()); 77 Thread.sleep(DELAY);//在兩個球顯示之間有延遲 78 } 79 } 80 catch (InterruptedException e)//中斷異常 81 { 82 } 83 } 84 } 85 86 BounceBounce
(2)在Elipse環境下除錯教材631頁程式14-4,結合程式執行結果理解程式;
1 package bounceThread; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 6 import javax.swing.*; 7 8 /** 9 * 顯示動畫彈跳球 10 * @version 1.34 2015-06-21 11 * @author Cay Horstmann 12 */ 13 public class BounceThread { 14 public static void main(String[] args) { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new BounceFrame(); 17 frame.setTitle("BounceThread"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 } 23 24 /** 25 * 框架與球元件和按鈕 26 */ 27 class BounceFrame extends JFrame { 28 private BallComponent comp; 29 public static final int STEPS = 1000; 30 public static final int DELAY = 5; 31 32 /** 33 * 用顯示彈跳球以及開始和關閉按鈕的元件構建框架 34 */ 35 public BounceFrame() { 36 comp = new BallComponent(); 37 add(comp, BorderLayout.CENTER); 38 JPanel buttonPanel = new JPanel(); 39 addButton(buttonPanel, "Start", event -> addBall()); 40 addButton(buttonPanel, "Close", event -> System.exit(0)); 41 add(buttonPanel, BorderLayout.SOUTH); 42 pack(); 43 } 44 45 /** 46 * 向容器新增按鈕 47 * 48 * @param c 49 * the container 50 * @param title 51 * the button title 52 * @param listener 53 * the action listener for the button 54 */ 55 public void addButton(Container c, String title, ActionListener listener) { 56 JButton button = new JButton(title); 57 c.add(button); 58 button.addActionListener(listener); 59 } 60 61 /** 62 * 在畫布上新增一個彈跳球,並啟動一個執行緒使其彈跳 63 */ 64 public void addBall() { 65 Ball ball = new Ball(); 66 comp.add(ball); 67 Runnable r = () -> { 68 try { 69 for (int i = 1; i <= STEPS; i++) { 70 ball.move(comp.getBounds());//將球移動到下一個位置,如果碰到其中一個邊緣則反轉方向 71 comp.repaint();//重繪此元件。 72 Thread.sleep(DELAY);//在指定的毫秒數內讓當前正在執行的執行緒休眠 73 } 74 } catch (InterruptedException e) { 75 } 76 }; 77 Thread t = new Thread(r); 78 t.start(); 79 } 80 } 81 82 BounceThreadBounceThread
測試程式3:分析以下程式執行結果並理解程式。
1 class Race extends Thread { 2 public static void main(String args[]) { 3 Race[] runner=new Race[4]; 4 for(int i=0;i<4;i++) runner[i]=new Race( ); 5 for(int i=0;i<4;i++) runner[i].start( ); 6 runner[1].setPriority(MIN_PRIORITY); 7 runner[3].setPriority(MAX_PRIORITY);} 8 public void run( ) { 9 for(int i=0; i<1000000; i++); 10 System.out.println(getName()+"執行緒的優先順序是"+getPriority()+"已計算完畢!"); 11 } 12 }
測試程式4
l 教材642頁程式模擬一個有若干賬戶的銀行,隨機地生成在這些賬戶之間轉移錢款的交易。每一個賬戶有一個執行緒。在每一筆交易中,會從執行緒所服務的賬戶中隨機轉移一定數目的錢款到另一個隨機賬戶。
在Elipse環境下除錯教材642頁程式14-5、14-6,結合程式執行結果理解程式;
B
1 package unsynch; 2 3 import java.util.*; 4 5 /** 6 * 有許多銀行賬戶的銀行 7 * @version 1.30 2004-08-01 8 * @author Cay Horstmann 9 */ 10 public class Bank 11 { 12 private final double[] accounts; 13 14 /** 15 * 建設銀行 16 * @param n 賬號 17 * @param initialBalance 每個賬戶的初始餘額 18 */ 19 public Bank(int n, double initialBalance) 20 { 21 accounts = new double[n]; 22 Arrays.fill(accounts, initialBalance); 23 } 24 25 /** 26 * 把錢從一個賬戶轉到另一個賬戶 27 * @param from 轉賬賬戶從 28 * @param to 轉賬賬戶到 29 * @param amount 轉讓的數額 30 */ 31 public void transfer(int from, int to, double amount) 32 { 33 if (accounts[from] < amount) return; 34 System.out.print(Thread.currentThread()); 35 accounts[from] -= amount; 36 System.out.printf(" %10.2f from %d to %d", amount, from, to); 37 accounts[to] += amount; 38 System.out.printf(" Total Balance: %10.2f%n", getTotalBalance()); 39 } 40 41 /** 42 * 獲取所有帳戶餘額的總和 43 * @return 總餘額 44 */ 45 public double getTotalBalance() 46 { 47 double sum = 0; 48 49 for (double a : accounts) 50 sum += a; 51 52 return sum; 53 } 54 55 /** 56 * 獲取銀行中的帳戶數量 57 * @return 賬號 58 */ 59 public int size() 60 { 61 return accounts.length; 62 } 63 } 64 65 Bankank
1 package unsynch; 2 3 /** 4 * 此程式顯示多個執行緒訪問資料結構時的資料損壞 5 * @version 1.31 2015-06-21 6 * @author Cay Horstmann 7 */ 8 public class UnsynchBankTest 9 { 10 public static final int NACCOUNTS = 100; 11 public static final double INITIAL_BALANCE = 1000; 12 public static final double MAX_AMOUNT = 1000; 13 public static final int DELAY = 10; 14 15 public static void main(String[] args) 16 { 17 Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE); 18 for (int i = 0; i < NACCOUNTS; i++) 19 { 20 int fromAccount = i; 21 Runnable r = () -> { 22 try 23 { 24 while (true) 25 { 26 int toAccount = (int) (bank.size() * Math.random()); 27 double amount = MAX_AMOUNT * Math.random(); 28 bank.transfer(fromAccount, toAccount, amount); 29 Thread.sleep((int) (DELAY * Math.random())); 30 } 31 } 32 catch (InterruptedException e) 33 { 34 } 35 }; 36 Thread t = new Thread(r); 37 t.start(); 38 } 39 } 40 } 41 42 UnsynchBankTestUnsynchBankTest
綜合程式設計練習
程式設計練習1
1.設計一個使用者資訊採集程式,要求如下:(1) 使用者資訊輸入介面如下圖所示:
(1) 使用者點選提交按鈕時,使用者輸入資訊顯示控制檯介面;
(2) 使用者點選重置按鈕後,清空使用者已輸入資訊;
(3) 點選視窗關閉,程式退出。
1 package AA; 2 3 4 5 import java.awt.EventQueue; 6 7 import javax.swing.JFrame; 8 9 public class Main { 10 public static void main(String[] args) { 11 EventQueue.invokeLater(() -> { 12 DemoJFrame page = new DemoJFrame(); 13 }); 14 } 15 } 16 17 MainMain
1 package AA; 2 3 import java.awt.Dimension; 4 import java.awt.Toolkit; 5 import java.awt.Window; 6 7 public class WinCenter { 8 public static void center(Window win){ 9 Toolkit tkit = Toolkit.getDefaultToolkit(); 10 Dimension sSize = tkit.getScreenSize(); 11 Dimension wSize = win.getSize(); 12 if(wSize.height > sSize.height){ 13 wSize.height = sSize.height; 14 } 15 if(wSize.width > sSize.width){ 16 wSize.width = sSize.width; 17 } 18 win.setLocation((sSize.width - wSize.width)/ 2, (sSize.height - wSize.height)/ 2); 19 } 20 } 21 22 WinCenterWinCenter
1 package o; 2 3 import java.awt.Dimension; 4 import java.awt.FlowLayout; 5 import java.awt.GridLayout; 6 7 import javax.swing.BorderFactory; 8 import javax.swing.ButtonGroup; 9 import javax.swing.JButton; 10 import javax.swing.JCheckBox; 11 import javax.swing.JComboBox; 12 import javax.swing.JFrame; 13 import javax.swing.JLabel; 14 import javax.swing.JPanel; 15 import javax.swing.JRadioButton; 16 import javax.swing.JTextField; 17 18 public class DemoJFrame extends JFrame { 19 private JPanel jPanel1; 20 private JPanel jPanel2; 21 private JPanel jPanel3; 22 private JPanel jPanel4; 23 private JTextField fieldname; 24 private JComboBox comboBox; 25 private JTextField fieldadress; 26 private ButtonGroup bg; 27 private JRadioButton Male; 28 private JRadioButton Female; 29 private JCheckBox read; 30 private JCheckBox sing; 31 private JCheckBox dance; 32 33 public DemoJFrame() { 34 // 設定視窗大小 35 this.setSize(800, 400); 36 // 設定可見性 37 this.setVisible(true); 38 // 設定標題 39 this.setTitle("程式設計練習一"); 40 // 設定關閉操作 41 this.setDefaultCloseOperation(EXIT_ON_CLOSE); 42 // 設定視窗居中 43 WinCenter.center(this); 44 // 建立四個面板物件 45 jPanel1 = new JPanel(); 46 setJPanel1(jPanel1); 47 jPanel2 = new JPanel(); 48 setJPanel2(jPanel2); 49 jPanel3 = new JPanel(); 50 setJPanel3(jPanel3); 51 jPanel4 = new JPanel(); 52 setJPanel4(jPanel4); 53 // 設定容器的為流佈局 54 FlowLayout flowLayout = new FlowLayout(); 55 this.setLayout(flowLayout); 56 // 將四個面板新增到容器中 57 this.add(jPanel1); 58 this.add(jPanel2); 59 this.add(jPanel3); 60 this.add(jPanel4); 61 62 } 63 64 /* 65 * 設定面一 66 */ 67 private void setJPanel1(JPanel jPanel) { 68 // TODO 自動生成的方法存根 69 jPanel.setPreferredSize(new Dimension(700, 45)); 70 // 給面板的佈局設定為網格佈局 一行4列 71 jPanel.setLayout(new GridLayout(1, 4)); 72 73 JLabel name = new JLabel("name:"); 74 name.setSize(100, 50); 75 fieldname = new JTextField(""); 76 fieldname.setSize(80, 20); 77 78 JLabel study = new JLabel("qualification:"); 79 comboBox = new JComboBox(); 80 comboBox.addItem("初中"); 81 comboBox.addItem("高中"); 82 comboBox.addItem("本科"); 83 jPanel.add(name); 84 jPanel.add(fieldname); 85 jPanel.add(study); 86 jPanel.add(comboBox); 87 88 } 89 90 /* 91 * 設定面板二 92 */ 93 private void setJPanel2(JPanel jPanel) { 94 // TODO 自動生成的方法存根 95 jPanel.setPreferredSize(new Dimension(700, 50)); 96 // 給面板的佈局設定為網格佈局 一行4列 97 jPanel.setLayout(new GridLayout(1, 4)); 98 99 JLabel name = new JLabel("address:"); 100 fieldadress = new JTextField(); 101 fieldadress.setPreferredSize(new Dimension(150, 50)); 102 103 JLabel study = new JLabel("hobby:"); 104 JPanel selectBox = new JPanel(); 105 selectBox.setBorder(BorderFactory.createTitledBorder("")); 106 selectBox.setLayout(new GridLayout(3, 1)); 107 read = new JCheckBox("reading"); 108 sing = new JCheckBox("singing"); 109 dance = new JCheckBox("danceing"); 110 selectBox.add(read); 111 selectBox.add(sing); 112 selectBox.add(dance); 113 jPanel.add(name); 114 jPanel.add(fieldadress); 115 jPanel.add(study); 116 jPanel.add(selectBox); 117 } 118 119 /* 120 * 設定面板三 121 */ 122 private void setJPanel3(JPanel jPanel) { 123 // TODO 自動生成的方法存根 124 jPanel.setPreferredSize(new Dimension(700, 150)); 125 FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT); 126 jPanel.setLayout(flowLayout); 127 JLabel sex = new JLabel("性別:"); 128 JPanel selectBox = new JPanel(); 129 selectBox.setBorder(BorderFactory.createTitledBorder("")); 130 selectBox.setLayout(new GridLayout(2, 1)); 131 bg = new ButtonGroup(); 132 Male = new JRadioButton("male"); 133 Female = new JRadioButton("female"); 134 bg.add(Male ); 135 bg.add(Female); 136 selectBox.add(Male); 137 selectBox.add(Female); 138 jPanel.add(sex); 139 jPanel.add(selectBox); 140 141 } 142 143 /* 144 * 設定面板四 145 */ 146 private void setJPanel4(JPanel jPanel) { 147 // TODO 自動生成的方法存根 148 jPanel.setPreferredSize(new Dimension(700, 150)); 149 FlowLayout flowLayout = new FlowLayout(FlowLayout.CENTER, 50, 10); 150 jPanel.setLayout(flowLayout); 151 jPanel.setLayout(flowLayout); 152 JButton sublite = new JButton("提交"); 153 JButton reset = new JButton("重置"); 154 sublite.addActionListener((e) -> valiData()); 155 reset.addActionListener((e) -> Reset()); 156 jPanel.add(sublite); 157 jPanel.add(reset); 158 } 159 160 /* 161 * 提交資料 162 */ 163 private void valiData() { 164 // TODO 自動生成的方法存根 165 // 拿到資料 166 String name = fieldname.getText().toString().trim(); 167 String xueli = comboBox.getSelectedItem().toString().trim(); 168 String address = fieldadress.getText().toString().trim(); 169 System.out.println(name); 170 System.out.println(xueli); 171 String hobbystring=""; 172 if (read.isSelected()) { 173 hobbystring+="reading "; 174 } 175 if (sing.isSelected()) { 176 hobbystring+="singing "; 177 } 178 if (dance.isSelected()) { 179 hobbystring+="dancing "; 180 } 181 System.out.println(address); 182 if (Male.isSelected()) { 183 System.out.println("male"); 184 } 185 if (Female.isSelected()) { 186 System.out.println("female"); 187 } 188 System.out.println(hobbystring); 189 } 190 191 /* 192 * 重置 193 */ 194 private void Reset() { 195 // TODO 自動生成的方法存根 196 fieldadress.setText(null); 197 fieldname.setText(null); 198 comboBox.setSelectedIndex(0); 199 read.setSelected(false); 200 sing.setSelected(false); 201 dance.setSelected(false); 202 bg.clearSelection(); 203 } 204 } 205 206 DemoJFrameDemoJFrame
2.建立兩個執行緒,每個執行緒按順序輸出5次“你好”,每個“你好”要標明來自哪個執行緒及其順序號。
1 package BB; 2 3 4 class xian1 extends Thread { 5 public void run() 6 { 7 for(int i=1;i<=5;i++) 8 { System.out.println( i+ "你好"+" 來自執行緒1"); 9 try{ sleep(200); } 10 catch(InterruptedException e)//異常捕獲 11 { System.out.println("Lefthand error.");} 12 } 13 } 14 } 15 16 class xian2 extends Thread { 17 public void run() 18 { 19 for(int i=1;i<=5;i++) 20 { System.out.println( i+ "你好"+" 來自執行緒2"); 21 try{ sleep(200); } 22 catch(InterruptedException e)//異常捕獲 23 { System.out.println("Lefthand error.");} 24 } 25 } 26 27 } 28 public class xiancheng 29 { 30 //屬性 31 static xian1 xian11; 32 static xian2 xian22; 33 public static void main(String[] args) 34 { xian11=new xian1(); 35 xian22=new xian2(); 36 //用start()方法啟動執行緒 37 xian11.start(); 38 xian22.start(); 39 } 40<