201771010111李瑞紅《第十六週學習總結》

1、理論知識java

 多線程是進程執行過程當中產生的多條執行線索。線程是比進程執行更小的單位。線程不能獨立存在,必須存在於進程中,同一進程的各線程間共享進程空間的數據。每一個線程有它自身的產生、存在和消亡的過程,是一個動態的概念。多線程意味着一個程序的多行語句能夠看上去幾乎在同一時間內同時運行。線程建立、銷燬和切換的負荷遠小於進程,又稱爲輕量級進程。編程

線程兩種建立方法比較:實現Runnable接口的優點:符合OO設計的思想;便於用extends繼承其它類。採用繼承Thread類方法的優勢:代碼簡單。canvas

線程的終止:當線程的run方法執行方法體中最後一條語句後,或者出現了在run方法中沒有捕獲的異常時,線程將終止,讓出CPU使用權。調用interrupt()方法也可終止線程。 void interrupt() :向一個線程發送一箇中斷請求,同時把這個線程的「interrupted」狀態置爲true。若該線程處於 blocked 狀 態,會拋出 InterruptedException。數據結構

測試線程是否被中斷的方法:static boolean interrupted() :檢測當前線程是否已被中斷,並重置狀態 「interrupted」值爲false。  boolean isInterrupted() :檢測當前線程是否已被中斷 , 不改變狀態 「interrupted」值 。多線程

利用各線程的狀態變換,能夠控制各個線程輪流 使用CPU,體現多線程的並行性特徵。dom

Java實現多線程有兩種途徑:建立Thread類的子類;在程序中定義實現Runnable接口的類。ide

用Thread類的子類建立線程:首先需從Thread類派生出一個子類,在該子類中重寫run()方法。而後用建立該子類的對象Lefthand left=new Lefthand(); Righthand right=new Righthand();最後用start()方法啓動線程 left.start(); right.start();工具

用Thread類的子類建立多線程的關鍵性操做:定義Thread類的子類並實現用戶線程操做,即run()方法的實現。在適當的時候啓動線程。因爲Java只支持單重繼承,用這種方法定義的類不可再繼承其餘父類。佈局

用Runnable()接口實現線程:首先設計一個實現Runnable接口的類;而後在類中根據須要重寫run方法;再建立該類對象,以此對象爲參數創建Thread 類的對象;調用Thread類對象的start方法啓動線程,將 CPU執行權轉交到run方法。測試

Thread(Runnable r):建立一個新線程,它調用r的run(), r是一個實現了Runnable接口的類的實例。

  測試線程是否被中斷的方法:static boolean interrupted() :檢測當前線程是否已被中斷,並重置狀態 「interrupted」值爲false。  boolean isInterrupted() :檢測當前線程是否已被中斷 , 不改變狀態 「interrupted」值 。

利用各線程的狀態變換,能夠控制各個線程輪流 使用CPU,體現多線程的並行性特徵。

線程有以下7種狀態:New (新建);Runnable (可運行);Running(運行) ;Blocked (被阻塞) ;Waiting (等待) ;Timed waiting (計時等待) ; Terminated (被終止)。

   new(新建):線程對象剛剛建立,尚未啓動,此時線程還處於不可運行狀態。例如: Thread thread=new Thread(r); 此時線程thread處於新建狀態,有了相應的內存空間以及其它資源。

   runnable(可運行狀態):此時線程已經啓動,處於線程的run()方法之中。此時的線程可能運行,也可能不運行,只要 CPU一空閒,立刻就會運行。調用線程的start()方法可以使線程處於「可運行」狀態。例如: thread.start();

   blocked (被阻塞):一個正在執行的線程因特殊緣由,被暫停執行,進入阻塞狀態。阻塞時線程不能進入隊列排隊,必須等到引發阻塞的緣由消除,纔可從新進入排隊隊列。引發阻塞的緣由不少,不一樣緣由要用不一樣的方法解除。sleep(),wait()是兩個經常使用引發線程阻塞的方法。

線程阻塞的三種狀況:等待阻塞:經過調用線程的wait()方法,讓線程等待某工做的完成。同步阻塞:線程在獲取synchronized同步鎖失敗(由於鎖被其它線程所佔用),它會進入同步阻 塞狀態。 其餘阻塞:經過調用線程的sleep()或join() 或發出了I/O請求時,線程會進入到阻塞狀態。當 sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入就緒狀態。

Terminated (被終止) :線程被終止的緣由有二:一是run()方法中最後一個語句執行完畢而自 然死亡。二是由於一個沒有捕獲的異常終止了run方法而意外死亡。能夠調用線程的 stop 方法殺死一個線程(thread.stop();),可是,stop方法已過期,不要在本身的代碼中調用它。

線程的掛起和恢復: suspend() 和 resume() 方法:兩個方法可配套使用,suspend()使得線程進入阻塞狀態,而且不會自動恢復,必須其對應的 resume()被調用, 才能使得線程從新進入可執行狀態。但這種方法很容易引發線程死鎖問題,已不推薦使用。

其餘判斷和影響線程狀態的方法:join():等待指定線程的終止。 join(long millis):通過指定時間等待終止指定的線程。 isAlive():測試當前線程是否在活動。  yield():讓當前線程由「運行狀態」進入到「就緒狀態」 ,從而讓其它具備相同優先級的等待線程獲取執行權。

Thread類有三個與線程優先級有關的靜態量: MAX_PRIORITY:最大優先權,值爲10; MIN_PRIORITY:最小優先權,值爲1;  NORM _PRIORITY:默認優先權,值爲5。

調用setPriority(int a)重置當前線程的優先級,a取值能夠是前述的三個靜態量。調用getPriority()得到當前線程優先級。

下面幾種狀況下,當前運行線程會放棄CPU:線程調用了yield() 或sleep() 方法;搶先式系統下,有高優先級的線程參與調度;因爲當前線程進行I/O訪問、外存讀寫、等待用 戶輸入等操做致使線程阻塞;或者是爲等候一個條件變量,以及線程調用wait() 方法。

守護線程的唯一用途是爲其餘線程提供服務。例如計時線程。在一個線程啓動以前,調用setDaemon方法可將線程轉換爲守護線程。例如:setDaemon(true)

在Java中解決多線程同步問題的方法有兩種:J ava SE 5.0中引入ReentrantLock類。 在共享內存的類方法前加synchronized修飾符。

有關鎖對象和條件對象的關鍵要點:鎖用來保護代碼片斷,保證任什麼時候刻只能有一個線程執行被保護的代碼。鎖管理試圖進入被保護代碼段的線程。鎖可擁有一個或多個相關條件對象。每一個條件對象管理那些已經進入被保護的代碼 段但還不能運行的線程。

2、實驗部分

一、實驗目的與要求

(1) 掌握線程概念;

(2) 掌握線程建立的兩種技術;

(3) 理解和掌握線程的優先級屬性及調度方法;

(4) 掌握線程同步的概念及實現技術;

二、實驗內容和步驟

實驗1:測試程序並進行代碼註釋。

測試程序1:

l 在elipse IDE中調試運行ThreadTest,結合程序運行結果理解程序;

l 掌握線程概念;

l 掌握用Thread的擴展類實現線程的方法;

l 利用Runnable接口改造程序,掌握用Runnable接口建立線程的方法。

class Lefthand extends Thread { 

   public void run()

   {

       for(int i=0;i<=5;i++)

       {  System.out.println("You are Students!");

           try{   sleep(500);   }

           catch(InterruptedException e)

           { System.out.println("Lefthand error.");}    

       } 

  } 

}

class Righthand extends Thread {

    public void run()

    {

         for(int i=0;i<=5;i++)

         {   System.out.println("I am a Teacher!");

             try{  sleep(300);  }

             catch(InterruptedException e)

             { System.out.println("Righthand error.");}

         }

    }

}

public class ThreadTest 

{

     static Lefthand left;

     static Righthand right;

     public static void main(String[] args)

     {     left=new Lefthand();

           right=new Righthand();

           left.start();

           right.start();

     }

}

用Runnable接口改造程序的程序:

lass Lefthand implements Runnable {
    public void run() {
        for (int i = 0; i <= 5; i++) {
            System.out.println("You are Students!");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println("Lefthand error.");
            }
        }
    }

}

class Righthand implements Runnable {
    public void run() {
        for (int i = 0; i <= 5; i++) {
            System.out.println("I am a Teacher!");
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                System.out.println("Righthand error.");
            }
        }

    }

}

public class ThreadTest {
    static Thread left;
    static Thread right;

    public static void main(String[] args) {
        Runnable a = new Lefthand();
        Runnable b = new Righthand();
        left = new Thread(a);
        right = new Thread(b);
        left.startq();
        right.start();
    }
}

測試程序2:

l 在Elipse環境下調試教材625頁程序14-一、14-2 、14-3,結合程序運行結果理解程序;

 

package bounce;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Shows an animated bouncing ball.
 * 
 * @version 1.34 2015-06-21
 * @author Cay Horstmann
 */
public class Bounce {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new BounceFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}

/**
 * The frame with ball component and buttons.
 */
class BounceFrame extends JFrame {
    private BallComponent comp;
    public static final int STEPS = 1000;
    public static final int DELAY = 3;

    /**
     * Constructs the frame with the component for showing the bouncing ball and
     * Start and Close buttons
     */
    public BounceFrame() {
        setTitle("Bounce");// 設置窗體的標題
        comp = new BallComponent();
        add(comp, BorderLayout.CENTER);// 中間區域的佈局約束
        JPanel buttonPanel = new JPanel();
        addButton(buttonPanel, "Start", event -> addBall());// 添加Start按鈕
        addButton(buttonPanel, "Close", event -> System.exit(0));// 添加Close按鈕
        add(buttonPanel, BorderLayout.SOUTH);// 南區域的佈局約束
        pack();// 調整窗口大小
    }

    /**
     * Adds a button to a container.
     * 
     * @param c
     *            the container
     * @param title
     *            the button title
     * @param listener
     *            the action listener for the button
     */
    public void addButton(Container c, String title, ActionListener listener) {
        JButton button = new JButton(title);
        c.add(button);
        button.addActionListener(listener);
    }

    /**
     * Adds a bouncing ball to the panel and makes it bounce 1,000 times.
     */
    public void addBall() {
        try {
            Ball ball = new Ball();
            comp.add(ball);

            for (int i = 1; i <= STEPS; i++) {
                ball.move(comp.getBounds());
                comp.paint(comp.getGraphics());
                Thread.sleep(DELAY);// 在指定的毫秒數內讓當前正在執行的線程休眠
            }
        } catch (InterruptedException e) {
        }
    }
}
package bounce;

import java.awt.geom.*;

/**
 * A ball that moves and bounces off the edges of a rectangle
 * 
 * @version 1.33 2007-05-17
 * @author Cay Horstmann
 */
public class Ball {
    private static final int XSIZE = 15;
    private static final int YSIZE = 15;
    private double x = 0;
    private double y = 0;
    private double dx = 1;
    private double dy = 1;

    /**
     * Moves the ball to the next position, reversing direction if it hits one of
     * the edges
     */
    public void move(Rectangle2D bounds) {
        x += dx;
        y += dy;
        if (x < bounds.getMinX()) {
            x = bounds.getMinX();// 以 double 精度返回 Shape 窗體矩形的最小 X 座標
            dx = -dx;
        }
        if (x + XSIZE >= bounds.getMaxX()) {
            x = bounds.getMaxX() - XSIZE;
            dx = -dx;
        }
        if (y < bounds.getMinY()) {
            y = bounds.getMinY();// 以 double 精度返回 Shape 窗體矩形的最小 Y 座標
            dy = -dy;
        }
        if (y + YSIZE >= bounds.getMaxY()) {
            y = bounds.getMaxY() - YSIZE;
            dy = -dy;
        }
    }

    /**
     * Gets the shape of the ball at its current position.
     */
    public Ellipse2D getShape() {
        return new Ellipse2D.Double(x, y, XSIZE, YSIZE);// 根據指定座標構造和初始化 Ellipse2D
    }
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);
    }
}

l 在Elipse環境下調試教材631頁程序14-4,結合程序運行結果理解程序;

 

package bounceThread;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

/**
 * Shows animated bouncing balls.
 * 
 * @version 1.34 2015-06-21
 * @author Cay Horstmann
 */
public class BounceThread {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new BounceFrame();
            frame.setTitle("BounceThread");//設置標題
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}

/**
 * The frame with panel and buttons.
 */
class BounceFrame extends JFrame {
    private BallComponent comp;
    public static final int STEPS = 1000;
    public static final int DELAY = 5;

    /**
     * Constructs the frame with the component for showing the bouncing ball and
     * Start and Close buttons
     */
    public BounceFrame() {
        comp = new BallComponent();
        add(comp, BorderLayout.CENTER);//中間區域的佈局約束
        JPanel buttonPanel = new JPanel();//建立具備雙緩衝和流佈局的新 JPanel。
        addButton(buttonPanel, "Start", event -> addBall());//添加Start按鈕
        addButton(buttonPanel, "Close", event -> System.exit(0));//添加Close按鈕
        add(buttonPanel, BorderLayout.SOUTH);//南區域的佈局約束(容器底部)
        pack();//調整窗口的大小
    }

    /**
     * Adds a button to a container.
     * 
     * @param c        the container
     * @param title    the button title
     * @param listener the action listener for the button
     */
    public void addButton(Container c, String title, ActionListener listener) {
        JButton button = new JButton(title);
        c.add(button);
        button.addActionListener(listener);
    }

    /**
     * Adds a bouncing ball to the canvas and starts a thread to make it bounce
     */
    public void addBall() {
        Ball ball = new Ball();
        comp.add(ball);
        Runnable r = () -> {
            try {
                for (int i = 1; i <= STEPS; i++) {
                    ball.move(comp.getBounds());
                    comp.repaint();//重繪組件
                    Thread.sleep(DELAY);//在指定的毫秒數內讓當前正在執行的線程休眠
                }
            } catch (InterruptedException e) {
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
}


package bounceThread;

import java.awt.geom.*;

/**
   A ball that moves and bounces off the edges of a 
   rectangle
 * @version 1.33 2007-05-17
 * @author Cay Horstmann
*/
public class Ball
{
   private static final int XSIZE = 15;
   private static final int YSIZE = 15;
   private double x = 0;
   private double y = 0;
   private double dx = 1;
   private double dy = 1;

   /**
      Moves the ball to the next position, reversing direction
      if it hits one of the edges
   */
   public void move(Rectangle2D bounds)
   {
      x += dx;
      y += dy;
      if (x < bounds.getMinX())
      { 
         x = bounds.getMinX();//以 double 精度返回 Shape 窗體矩形的最小 X 座標
         dx = -dx;
      }
      if (x + XSIZE >= bounds.getMaxX())
      {
         x = bounds.getMaxX() - XSIZE; 
         dx = -dx; 
      }
      if (y < bounds.getMinY())
      {
         y = bounds.getMinY(); //根據指定座標構造和初始化 Ellipse2D
         dy = -dy;
      }
      if (y + YSIZE >= bounds.getMaxY())
      {
         y = bounds.getMaxY() - YSIZE;
         dy = -dy; 
      }
   }

   /**
      Gets the shape of the ball at its current position.
   */
   public Ellipse2D getShape()
   {
      return new Ellipse2D.Double(x, y, XSIZE, YSIZE);//根據指定座標構造和初始化 Ellipse2D
   }
}
package bounceThread;

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 JComponent {
    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 panel.
     * 
     * @param b the ball to add
     */
    public void add(Ball b) {
        balls.add(b);
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        for (Ball b : balls) {
            g2.fill(b.getShape());
        }
    }

    public Dimension getPreferredSize() {
        return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);//構造一個 Dimension,並將其初始化爲指定寬度和高度。
    }
}

l 對比兩個程序,理解線程的概念和用途;

l 掌握線程建立的兩種技術。

測試程序3:分析如下程序運行結果並理解程序。

 

class Race extends Thread {
    public static void main(String args[]) {
        Race[] runner = new Race[4];
        for (int i = 0; i < 4; i++)
            runner[i] = new Race();
        for (int i = 0; i < 4; i++)
            runner[i].start();
        runner[1].setPriority(MIN_PRIORITY);
        runner[3].setPriority(MAX_PRIORITY);
    }

    public void run() {
        for (int i = 0; i < 1000000; i++);// 執行空語句,用來延時,也能夠換成sleep,sleep會釋放CPU,會拋出異常
        System.out.println(getName() + "線程的優先級是" + getPriority() + "已計算完畢!");
    }
}

測試程序4

l 教材642頁程序模擬一個有若干帳戶的銀行,隨機地生成在這些帳戶之間轉移錢款的交易。每個帳戶有一個線程。在每一筆交易中,會從線程所服務的帳戶中隨機轉移必定數目的錢款到另外一個隨機帳戶。

l 在Elipse環境下調試教材642頁程序14-五、14-6,結合程序運行結果理解程序;

 

package unsynch;

import java.util.*;

/**
 * 有許多銀行帳戶的銀行。
 * @version 1.30 2004-08-01
 * @author Cay Horstmann
 */
public class Bank
{
   private final double[] accounts;

   /**
    *構建了銀行。
    * @param n帳戶數量
    * @param 每一個賬戶的初始餘額
    */
   public Bank(int n, double initialBalance)
   {
      accounts = new double[n];
      Arrays.fill(accounts, initialBalance);
   }

   /**
    * 把錢從一個帳戶轉到另外一個帳戶。
    * @param 從帳戶轉出
    * @param 到帳轉到
    * @param 轉賬金額
    */
   public void transfer(int from, int to, double amount)
   {
      if (accounts[from] < amount) return;
      System.out.print(Thread.currentThread());
      accounts[from] -= amount;
      System.out.printf(" %10.2f from %d to %d", amount, from, to);
      accounts[to] += amount;
      System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
   }

   /**
    * 獲取全部賬戶餘額的總和。
    * @return 總平衡
    */
   public double getTotalBalance()
   {
      double sum = 0;

      for (double a : accounts)
         sum += a;

      return sum;
   }

   /**
    * 獲取銀行中的賬戶編號。
    * @return 帳戶數量
    */
   public int size()
   {
      return accounts.length;
   }
}
package unsynch;

/**
 * 當多個線程訪問一個數據結構時,這個程序顯示數據損壞。
 * @version 1.31 2015-06-21
 * @author Cay Horstmann
 */
public class UnsynchBankTest
{
   public static final int NACCOUNTS = 100;
   public static final double INITIAL_BALANCE = 1000;
   public static final double MAX_AMOUNT = 1000;
   public static final int DELAY = 10;
   
   public static void main(String[] args)
   {
      Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
      for (int i = 0; i < NACCOUNTS; i++)
      {
         int fromAccount = i;
         Runnable r = () -> {
            try
            {
               while (true)
               {
                  int toAccount = (int) (bank.size() * Math.random());
                  double amount = MAX_AMOUNT * Math.random();
                  bank.transfer(fromAccount, toAccount, amount);
                  Thread.sleep((int) (DELAY * Math.random()));
               }
            }
            catch (InterruptedException e)
            {
            }            
         };
         Thread t = new Thread(r);
         t.start();
      }
   }
}

綜合編程練習

編程練習1

1. 設計一個用戶信息採集程序,要求以下:

(1) 用戶信息輸入界面以下圖所示:

(2) 用戶點擊提交按鈕時,用戶輸入信息顯示控制檯界面;

(3) 用戶點擊重置按鈕後,清空用戶已輸入信息;

(4) 點擊窗口關閉,程序退出。

package t;

import java.awt.EventQueue;

import javax.swing.JFrame;

public class Mian {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            DemoJFrame page = new DemoJFrame();
        });
    }
}
package t;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;

public class WinCenter {
    public static void center(Window win){
        Toolkit tkit = Toolkit.getDefaultToolkit();//獲取默認工具包
        Dimension sSize = tkit.getScreenSize();//獲取屏幕的大小
        Dimension wSize = win.getSize();
        if(wSize.height > sSize.height){
            wSize.height = sSize.height;
        }
        if(wSize.width > sSize.width){
            wSize.width = sSize.width;
        }
        win.setLocation((sSize.width - wSize.width)/ 2, (sSize.height - wSize.height)/ 2);//將組件移到新的位置
    }
}
package t;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class Demo extends JFrame {
    public Demo() {
        JPanel panel1 = new JPanel();
        panel1.setPreferredSize(new Dimension(700, 45));
        panel1.setLayout(new GridLayout(1, 4));
        JLabel label1 = new JLabel("Name:");
        JTextField j1 = new JTextField("");
        JLabel label2 = new JLabel("Qualification:");
        JComboBox<Object> j2 = new JComboBox<>();
        j2.addItem("Graduate");
        j2.addItem("Not Graduate");
        panel1.add(label1);
        panel1.add(j1);
        panel1.add(label2);
        panel1.add(j2);

        JPanel panel2 = new JPanel();
        panel2.setPreferredSize(new Dimension(700, 50));
        panel2.setLayout(new GridLayout(1, 4));
        JLabel label3 = new JLabel("Address:");
        JTextArea j3 = new JTextArea();
        JLabel label4 = new JLabel("Hobby:");
        JPanel p = new JPanel();
        p.setLayout(new GridLayout(3, 1));
        p.setBorder(BorderFactory.createLineBorder(null));
        JCheckBox c1 = new JCheckBox("Reading");
        JCheckBox c2 = new JCheckBox("Singing");
        JCheckBox c3 = new JCheckBox("Dancing");
        p.add(c1);
        p.add(c2);
        p.add(c3);
        panel2.add(label3);
        panel2.add(j3);
        panel2.add(label4);
        panel2.add(p);

        JPanel panel3 = new JPanel();
        panel3.setPreferredSize(new Dimension(700, 150));
        FlowLayout flowLayout1 = new FlowLayout(FlowLayout.CENTER, 50, 10);
        panel3.setLayout(flowLayout1);
        JLabel label5 = new JLabel("Sex:");
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(2, 1));
        p1.setBorder(BorderFactory.createLineBorder(null));
        ButtonGroup bu = new ButtonGroup();
        JRadioButton jr1 = new JRadioButton("Male");
        JRadioButton jr2 = new JRadioButton("Female");
        bu.add(jr1);
        bu.add(jr2);
        p1.add(jr1);
        p1.add(jr2);
        panel3.add(label5);
        panel3.add(p1);
        add(panel1);
        add(panel2);
        add(panel3);

        JPanel panel4 = new JPanel();
        panel4.setPreferredSize(new Dimension(700, 150));
        JButton b1 = new JButton("Validate");
        panel4.add(b1);
        JButton b2 = new JButton("Reset");
        panel4.add(b2);
        add(panel4);

        FlowLayout flowLayout = new FlowLayout();
        this.setLayout(flowLayout);
        this.setTitle("Students Detail");
        this.setBounds(200, 200, 800, 400);
        this.setVisible(true);
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        b1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                String xueli = j2.getSelectedItem().toString();
                System.out.println("Name:" + j1.getText());
                System.out.println("Qualification:" + xueli);
                String hobbystring = "Hobby:";
                if (c1.isSelected()) {
                    hobbystring += "Reading";
                }
                if (c2.isSelected()) {
                    hobbystring += "Singing";
                }
                if (c3.isSelected()) {
                    hobbystring += "Dancing";
                }
                System.out.println("Address:" + j3.getText());
                if (jr1.isSelected()) {
                    System.out.println("Sex:Male");
                }
                if (jr2.isSelected()) {
                    System.out.println("Sex:Female");
                }
                System.out.println(hobbystring);
            }
        });
        b2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                j1.setText(null);
                j3.setText(null);
                j2.setSelectedIndex(0);
                c1.setSelected(false);
                c2.setSelected(false);
                c3.setSelected(false);
                bu.clearSelection();
            }
        });
    }

   

2.建立兩個線程,每一個線程按順序輸出5次「你好」,每一個「你好」要標明來自哪一個線程及其順序號。

 

class Lefthand implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(i + 1 + ":a.你好!");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println("Lefthand error.");
            }
        }
    }
}

class Righthand implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(i + 1 + ":b.你好!");
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                System.out.println("Righthand error.");
            }
        }
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        Runnable left = new Lefthand();
        Thread l = new Thread(left);
        Runnable right = new Righthand();
        Thread r = new Thread(right);
        l.start();
        r.start();
    }
}

3. 完善實驗十五 GUI綜合編程練習程序。

身份證:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;

public class Main extends JFrame {
    private static ArrayList<Card> cardlist;
    private static ArrayList<Card> list;
    private JPanel panel;
    private JPanel Panel1;
    private static final int DEFAULT_WITH = 600;
    private static final int DEFAULT_HEIGHT = 300;

    public Main() {
        cardlist = new ArrayList<>();
        Scanner scanner = new Scanner(System.in);
        File file = new File("E:\\身份證號.txt");
        try {
            FileInputStream fis = new FileInputStream(file);
            BufferedReader in = new BufferedReader(new InputStreamReader(fis));
            String temp = null;

            while ((temp = in.readLine()) != null) {
                Scanner linescanner = new Scanner(temp);
                linescanner.useDelimiter(" ");
                String name = linescanner.next();
                String id = linescanner.next();
                String sex = linescanner.next();
                String age = linescanner.next();
                String area = linescanner.nextLine();

                Card card = new Card();
                card.setName(name);
                card.setId(id);
                card.setSex(sex);
                int a = Integer.parseInt(age);
                card.setAge(a);
                card.setArea(area);

                cardlist.add(card);
            }

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            System.out.println("信息文件找不到");
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println("信息文件讀取錯誤");
            e.printStackTrace();
        }
        panel = new JPanel();
        panel.setLayout(new BorderLayout());
        JTextArea jt = new JTextArea();
        panel.add(jt);
        add(panel, BorderLayout.NORTH);
        Panel1 = new JPanel();
        Panel1.setLayout(new GridLayout(1, 9));
        JButton jButton = new JButton("字典排序");
        JButton jButton1 = new JButton("年齡最大和年齡最小");
        JLabel lab = new JLabel("尋找老鄉:", Label.LEFT);
        JTextField jt1 = new JTextField();
        JLabel lab1 = new JLabel("尋找年齡相近的人:", Label.LEFT);
        JTextField jt2 = new JTextField();
        JLabel lab2 = new JLabel("輸入你的身份證號碼:", Label.LEFT);
        JTextField jt3 = new JTextField();
        JButton jButton2 = new JButton("退出");

        jButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                Collections.sort(cardlist);
                jt.setText(cardlist.toString());

            }
        });

        jButton1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                int max = 0, min = 100;
                int j, k1 = 0, k2 = 0;
                for (int i = 1; i < cardlist.size(); i++) {
                    j = cardlist.get(i).getAge();
                    if (j > max) {
                        max = j;
                        k1 = i;
                    }
                    if (j < min) {
                        min = j;
                        k2 = i;
                    }
                }
                jt.setText("年齡最大:" + cardlist.get(k1) + "年齡最小:" + cardlist.get(k2));
            }
        });

        jButton2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
                System.exit(0);
            }
        });
        jt1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String find = jt1.getText();
                String text = "";
                String place = find.substring(0, 3);
                for (int i = 0; i < cardlist.size(); i++) {
                    if (cardlist.get(i).getArea().substring(1, 4).equals(place)) {
                        text += "\n" + cardlist.get(i);
                        jt.setText("老鄉:" + text);
                    }
                }
            }
        });
        jt2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String yourage = jt2.getText();
                int a = Integer.parseInt(yourage);
                int near = agenear(a);
                jt.setText("年齡相近:" + cardlist.get(near));
            }
        });
        jt3.addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                // TODO 自動生成的方法存根
                list = new ArrayList<>();
                Collections.sort(cardlist);
                String key = jt3.getText();
                for (int i = 1; i < cardlist.size(); i++) {
                    if (cardlist.get(i).getId().contains(key)) {
                        list.add(cardlist.get(i));
                        jt.setText("你多是:\n" + list);
                    }
                }
            }
        });
        Panel1.add(jButton);
        Panel1.add(jButton1);
        Panel1.add(lab);
        Panel1.add(jt1);
        Panel1.add(lab1);
        Panel1.add(jt2);
        Panel1.add(lab2);
        Panel1.add(jt3);
        Panel1.add(jButton2);
        add(Panel1, BorderLayout.SOUTH);
        setSize(DEFAULT_WITH, DEFAULT_HEIGHT);
    }

    public static int agenear(int age) {
        int j = 0, min = 100, value = 0, k = 0;
        for (int i = 0; i < cardlist.size(); i++) {
            value = cardlist.get(i).getAge() - age;
            if (value < 0)
                value = -value;
            if (value < min) {
                min = value;
                k = i;
            }
        }
        return k;
    }
}
public class Card implements Comparable<Card> {
    private String name;
    private String id;
    private String sex;
    private int age;
    private String area;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public int compareTo(Card c) {
        return this.name.compareTo(c.getName());
    }

    public String toString() {
        return name + "\t" + id + "\t" + sex + "\t" + age + "\t" + area + "\n";
    }
}
import java.awt.*;
import javax.swing.*;

public class CardTest {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new Main();
            frame.setTitle("身份證");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}

四則運算

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;

public class Demo extends JFrame {
    int i = 0, i1 = 0, k = 0, sum = 0;
    private PrintWriter out = null;
    private String[] c1 = new String[10];
    private String[] c2 = new String[10];

    public Demo() {
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(1, 3));
        JTextArea jt1 = new JTextArea();
        JTextField jt2 = new JTextField();
        JTextArea jt3 = new JTextArea();
        panel.add(jt1);
        panel.add(jt2);
        panel.add(jt3);
        add(panel, BorderLayout.NORTH);

        JPanel panel1 = new JPanel();
        panel1.setLayout(new GridLayout(1, 2));
        Button button1 = new Button("生成題目");

        Button button2 = new Button("生成文件");
        panel1.add(button1);
        panel1.add(button2);

        add(panel1, BorderLayout.SOUTH);
        setSize(600, 300);
        button1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                jt2.setText(null);
                jt3.setText(null);
                if (i < 10) {
                    int a = (int) (Math.random() * 100);
                    int b = (int) (Math.random() * 100);
                    int m = (int) Math.round(Math.random() * 3);
                    switch (m) {
                    case 0:
                        while (b == 0 || a % b != 0) {
                            b = (int) Math.round(Math.random() * 100);
                            a = (int) Math.round(Math.random() * 100);
                        }
                        jt1.setText(i + 1 + ": " + a + "/" + b + "=");
                        c1[i] = jt1.getText();
                        k = a / b;
                        i++;
                        break;
                    case 1:
                        jt1.setText(i + 1 + ": " + a + "*" + b + "=");
                        c1[i] = jt1.getText();
                        k = a * b;
                        i++;
                        break;
                    case 2:
                        jt1.setText(i + 1 + ": " + a + "+" + b + "=");
                        c1[i] = jt1.getText();
                        k = a + b;
                        i++;
                        break;
                    case 3:
                        while (a < b) {
                            int x = a;
                            a = b;
                            b = x;
                        }
                        jt1.setText(i + 1 + ": " + a + "-" + b + "=");
                        c1[i] = jt1.getText();
                        k = a - b;
                        i++;
                        break;
                    }
                }
            }
        });
        jt2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                if (i < 11) {
                    int find = Integer.parseInt(jt2.getText());
                    String d = jt2.getText().toString().trim();
                    if (jt2.getText() != "") {
                        if (find == k) {
                            sum += 10;
                            jt3.setText("答案正確");
                        } else
                            jt3.setText("答案錯誤");
                    }
                    c2[i1] = d;
                    i1++;
                }
            }
        });
        button2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                try {
                    out = new PrintWriter("text.txt");
                } catch (FileNotFoundException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                for (int counter = 0; counter < 10; counter++) {
                    out.println(c1[counter] + c2[counter]);
                }
                out.println("成績爲" + sum);
                out.close();
            }
        });
    }
}
import java.awt.*;
import javax.swing.*;

public class DemoTest {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new Demo();
            frame.setTitle("計算題");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}

實驗總結:

多線程是進程執行過程當中產生的多條執行線索。線程是比進程執行更小的單位。線程不能獨立存在,必須存在於進程中,同一進程的各線程間共享進程空間的數據。每一個線程有它自身的產生、存在和消亡的過程,是一個動態的概念。多線程意味着一個程序的多行語句能夠看上去幾乎在同一時間內同時運行。線程建立、銷燬和切換的負荷遠小於進程,又稱爲輕量級進程。

線程兩種建立方法比較:實現Runnable接口的優點:符合OO設計的思想;便於用extends繼承其它類。採用繼承Thread類方法的優勢:代碼簡單。

Java 的線程調度採用優先級策略:優先級高的先執行,優先級低的後執行;多線程系統會自動爲每一個線程分配一個優先級,缺省時,繼承其父類的優先級; 任務緊急的線程,其優先級較高; 同優先級的線程按「先進先出」的隊列原則。

感覺:對佈局的大小設置不是太明白,感受有些參數變了可是佈局的大小並無發生變化。

相關文章
相關標籤/搜索