プロジェクト |
コンテンツ |
この作品は、コースに属し |
<教室の教師はホームリンクブログ> https://www.cnblogs.com/nwnu-daizh/ |
どこの仕事でこの要件 |
<ジョブリンクアドレス> https://www.cnblogs.com/nwnu-daizh/p/12031970.html |
ジョブの学習目標 |
(1)は、Javaアプリケーションパッケージ操作を習得。 (2)スレッドの概念を把握します。 (3)は、スレッドが作成された2つの技術を習得します。 (4)アプリケーションのGUIの研究デザイン。
|
パートI:教科書の知的内容の要約14.1から14.3
1.スレッドの概念:
プログラムは、アプリケーションの実行に基づいてモデル化され、静的コード、の一部です。
これは、コードから負荷に対応が、完全なプロセスが終了し実行するプログラムの実装の動的なプロセスです。
マルチスレッドは、生成されたプロセスの実行の実装に手がかりの数です。スレッドは、プロセスより小さな単位に実行されます。
スレッドが独立して存在することはできません、彼らはデータ共有プロセス空間の同じプロセスのスレッド間、プロセスに存在している必要があります。
-各スレッドは、プロセスの独自の生産、存在と終焉を持つ動的な概念です。
-マルチスレッドプログラムがほぼ同時に見て同時に実行することができますマルチライン文の手段。
( 2つの方法で経路2)は、Javaマルチスレッド:
lは 作成 Threadクラスのサブクラスを
<1> Threadクラスのサブクラスを使用してスレッドを作成するには
まず、必要性このサブクラスでは、サブクラスThreadクラス、オーバーライドrun()メソッドを導き出します。
例:
クラスハンドスレッド延び
{
公共ボイドRUNを()
{...}
}
<2>、次いでこのサブクラスのオブジェクト作成
左側左側左側左側新しい新しい左=();
右側右側新しい新しい右側右側右=();
スレッド開始する<3>最後に、start()メソッド
left.startを();
right.start()。
スレッドのサブクラスをマルチスレッド重要な操作の作成: - Threadクラスのサブクラスを定義し、run()メソッドを達成するために、すなわち、ユーザーねじ切り動作を実現。
- 適切な時期にスレッドを起動します。
そのため Javaは単一継承のみ、このように定義されたクラスができなくなっ継承他の親をサポートしていません。で定義されたプログラムに実装されたRunnableインタフェースクラス
( 2)のRunnable()インターフェース・スレッドと:
<1> まず、設計実装クラスのRunnableインターフェースと
<2> とに応じてクラスに書き換える必要がある実行方法;
<3> クラスのオブジェクトを作成する前に、このオブジェクトがパラメータとして確立されているスレッド・クラスのオブジェクト;
<4> コールスレッドを開始するスレッドクラスオブジェクトのメソッドを起動し、それがCPUの方法を実行する権利を実行に転送されます。
2.割り込みスレッド:
⚫最後の文でスレッドの実行方法ボディrunメソッドの後、または、そのためCPUの使用権を終了しますスレッドを捕捉しないrunメソッドで例外があったとき。
⚫()メソッド割り込み呼び出しがスレッドを終了することができます。
割り込みボイド()
-スレッドの「中断」状態がtrueに設定されている間、スレッドに割り込み要求を送信します。
-スレッドの状態がブロックされている場合、それがスローされます例外:InterruptedExceptionを。
(テストスレッドが中断されているかどうかを方法2)
Javaはスレッドが中断されたかどうかをテストするためのいくつかの方法が用意されています。
静的なブール値は、()⚫中断し
、現在のスレッドが割り込まれていると、リセット状態が「中断」かどうかを検出する偽であります- 。
ブールisInterruptedを⚫()
-現在のスレッドが割り込まれているかどうかを検出するには、状態を変更しない値を「中断」。
3.スレッドのステータス:
各スレッドによる状態遷移は、各スレッドの順番を制御するために使用することができる CPUを、マルチスレッド並列処理特性を具体化します。
⚫スレッドは、次の7つの状態があります。
➢新(新)
⚫新(新)
作成したスレッドオブジェクトは、開始されていない場合、スレッドは非動作状態にあります。例えば:スレッドのスレッドは、新しいスレッド(Rは= ); この場合、新しいスレッドのスレッドの状態を対応するメモリ空間と他のリソースと。
➢Runnableを(実行)
⚫実行可能(実行可能)
➢スレッドがスレッドの実行中のメソッドの中で、この時点で開始されています()。
➢スレッドがこの時点で実行することができる、または限り、CPUがアイドル状態になるように動作しない場合があり、それはすぐに実行されます。
➢スレッドのstart()メソッドを呼び出すと、スレッドが「実行可能」状態であることができます。例えば:thread.start();
➢実行中の(ランニング)
➢ブロックされ(ブロック)
⚫遮断(ブロック)
スレッドが実行中➢特別な理由は、ブロックされた状態に懸濁します。
ブロックされたスレッドがキューラインを入力できない場合、彼らはキューラインを再入力することができます前に排除するための閉塞を引き起こしまで➢、待たなければなりません。
➢障害物が多くの理由、リフトに異なる方法を使用するための様々な理由によって引き起こされます。
⚫睡眠()、待機()メソッドのスレッドがブロックされた2つの一般的な原因です。
➢待機(待機)
⚫ブロック待っている - スレッド待ち()メソッドを呼び出すことにより、スレッドは、ジョブの完了を待ちます。
➢時限待っている(待機しているタイミング)
➢終端(終了)
:二つの理由⚫終端(終了)スレッドが終了するがある
最後の文で➢まずrun()メソッドを終了し、自然の原因で死亡しているが。
➢秒を、中止されrunメソッドや不慮の死のない撮影がないため。
➢スレッドが()はThread.stop(;)スレッドを殺すためにstopメソッドを呼び出すことができます、しかし、stopメソッドは廃止され、独自のコードでそれを呼び出すことはありません。
衝撃およびスレッドの状態を決定するための他の方法
➢join():指定されたスレッドの終了を待ちます。
➢join(長いミリ):指定し、指定したスレッドの終了後に待機する時間。
➢isAlive():現在のスレッドの活動かどうかを試験します。
➢yield():現在のスレッドの「実行中の状態が」そう執行力に同一の優先アクセス権を持つ他の待機スレッドという「準備状態」にしてみましょう。
4.マルチスレッドのスケジューリング:
- Javaは、すべてのスレッドが実行可能状態に入った後、プログラムを開始した監視するスレッドスケジューラを提供します。スレッドスケジューラの優先度に応じて、スレッドが実行のためにスケジュールされるべきスレッドを決定します。
-同時に、レディキュー待ちのプロセッサリソースを入力する最初の実行可能スレッドでレディキュー内のスレッドには、複数であってもよいです。Javaのマルチスレッドシステムは、自動的に各スレッドのスレッドに優先順位を割り当てます。
⚫Javaはスレッドのスケジューリングは、優先順位のポリシーを使用しています:
➢優先度の高い、実行後の低優先度の最初の実装を、
➢マルチスレッドシステムは自動的にデフォルトで各スレッドに優先順位を割り当てます場合は、親クラスの優先順位継承レベル;
➢ミッション・クリティカルなスレッド、優先順位の高い;
➢同じ優先度のスレッドキューの「最初のうちで最初の」原理に従って、
⚫次のような状況の下で、現在実行中のスレッドがCPUを放棄します:
-スレッドが歩留まりを(呼び出す)またはスリープ()メソッド;
-関与プリエンプティブシステムの下で、優先度の高いスレッドのスケジューリング;
-私のために現在のスレッドのために/ Oユーザ入力などの操作を待ってアクセス、外部メモリの読み出し及び書き込みは、ブロックされたスレッドにつながっ;または条件変数を待って、スレッドの呼び出しが待機()メソッド。
問題の複数のスレッドの同時実行:
◆複数のスレッドの実行の相対的な順序は不明です。
◆スレッドの実行順序の不確実性は、結果の不確実性を作成します。
◆多くの場合、共有データにマルチスレッド操作で、この不確実性を生成します。
5.スレッド同期:
マルチスレッドの不確実性のソリューションを同時に実行:別のスレッドがこの方法を使用するように、スレッド同期メカニズムの導入、あなただけ待つことができます。
パートII:実験の部
1 、実験目的と要件
(1)マスタのJavaアプリケーションパッケージ操作を、
(2)スレッドの概念を把握します。
(3)は、スレッドが作成された2つの技術を習得します。
2 、実験及びステップ
実験 1: の導入第13章サンプルプログラム、テスト手順やコードのコメント。
試験手順1
リットル でelipse IDE 教科書試運転585 のページサイズ13-1 プログラムの理解を実行した結果と併せて、。
lの 生成別のディレクトリにJARファイルには、さらに、アーカイブが実行され、プログラムがリソースを確認することで、現在のディレクトリからJARファイルから読み込まれません。
Lが 作成できるようにJARのメソッドファイルを、
コードは以下のコメント
リソースをパッケージ化。 インポート持つjava.awt。*; 輸入java.io. *; 輸入java.net。*; 輸入java.utilの。*; インポートするjavax.swing。*; / ** * @version 1.41 2015年6月12日 * @authorケイHorstmann * / publicクラスResourceTest { パブリック静的無効メイン(文字列[] args) { EventQueue.invokeLater(() - > { JFrameのフレーム=新しいResourceTestFrame() ; frame.setTitle( "ResourceTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(TRUE); }); } } / ** * Aフレームロード画像とテキストリソースという。 * / クラスResourceTestFrame JFrameの延び { = 300 DEFAULT_WIDTH最終INTプライベート静的; = 300 DEFAULT_HEIGHT最終INTプライベート静的; 公共ResourceTestFrame() { のsetSize(DEFAULT_WIDTH、DEFAULT_HEIGHT); //はabout.gifアイコン用いて画像ファイルを作成する URL aboutURL =のgetClassを( ).getResource() "about.gif"; // URLのgetResource(文字列名) リソースとクラスを見つけるために同じ位置にある、戻りURLは、リソースのロードできる 画像のimg =新しい新しいイメージアイコン(aboutURL).getImage()を、 setIconImage( IMG); //ファイルABOUT.TXT読み JTextAreaのにtextArea =新しい新しいJTextAreaに(); 。のInputStreamストリーム=はgetClass()getResourceAsStream( "ABOUT.TXT"); //のInputStream getResourceAsStream(文字列名)は、リソースをロードすることができ返します入力ストリーム 試行(=新しい新しいスキャナスキャナ(ストリーム、で"UTF-8")) { 一方(in.hasNext()) textArea.append(in.nextLine()+ "\ n"は); } (にtextArea)を加えます。 } }
示すように実行します。
アーカイブ:
要約:リソース機構、非クラスファイル操作のためのステップ:1)リソース2とクラスオブジェクトを取得する)リソースは、画像や音声ファイルである場合、のgetResource(ファイル名)を呼び出す必要がURLのリソースの位置として取得し、次に使用されますgetAudioClipのgetImageメソッドまたは読み取り。3)異なる画像や音声ファイル、その他のリソースは、データファイルgetResourceAsStreamメソッドを読み取るために使用することができます。
試験手順2:
elipse IDEにおけるL デバッグの ThreadTest、プログラムの合成結果は、プログラムを理解されよ。
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(); } }
注释代码如下:
package a; //构建Thread类的子类定义线程 class Lefthand extends Thread { public void run() { for(int i=0;i<=5;i++) { System.out.println("You are Students!"); try{ sleep(500); //暂停,每0.5秒输出一次 } 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();//启动这个线程,引发调用run()方法。立即返回,新线程并发运行 right.start(); } }
运行结果如图:
利用Runnable接口改造程序如下:
package a; import javax.print.attribute.standard.RequestingUserName; class 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 Lefthand left; //static Righthand right; public static void main(String[] args) { // left=new Lefthand(); //right=new Righthand(); Runnable lefthand=new Lefthand(); Thread left=new Thread(lefthand);// Runnable没有start这个方法,需要将Runnable的对象被Thread引用才可在Thread中调用start方法 Runnable righthand=new Righthand(); Thread right=new Thread(righthand); left.start(); right.start(); } }
测试程序3:
l 在Elipse环境下调试教材625页程序14-1、14-2 、14-3,结合程序运行结果理解程序;
l 在Elipse环境下调试教材631页程序14-4,结合程序运行结果理解程序;
l 对比两个程序,理解线程的概念和用途;
l 掌握线程创建的两种技术。
Ball.java:
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(); dx = -dx; } if (x + XSIZE >= bounds.getMaxX()) { x = bounds.getMaxX() - XSIZE; dx = -dx; } if (y < bounds.getMinY()) { y = bounds.getMinY(); 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); } }
BallComponent.java:
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 JComponent { private static final int DEFAULT_WIDTH = 450; private static final int DEFAULT_HEIGHT = 350; private java.util.List<Ball> balls = new ArrayList<>();//构造一个初始容量为 10 的空列表。 //此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。 /** * 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); } }
BounceFrame.java:
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);//将自建的swing组件放在居中的位置 JPanel buttonPanel = new JPanel(); addButton(buttonPanel, "Start", event -> addBall()); addButton(buttonPanel, "Close", event -> System.exit(0));//将两个组件注册为事件源并添加到buttonpanel中 add(buttonPanel, BorderLayout.SOUTH);//将一个buttonpanel放到框架的南端 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); }//用addbutton方法将两个按钮组合为一个整体 /** * 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);//调用sleep并未创建线程对象,只是为了将两个球的轨迹可以显示出来 } } catch (InterruptedException e) { } } }
BounceFrame.java:
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(); addButton(buttonPanel, "Start", event -> addBall()); addButton(buttonPanel, "Close", event -> System.exit(0)); 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();//使得小球的移动成为其中的一个子线程 } }
运行结果如图:
开始截图:
未改进代码截图:
改进后的截图:
小结:两个程序的不同之处在于:第一个程序存在一定的缺陷,在该程序中,小球的运动轨迹的显示只是程序的一部分,当点击start开始后,在程序运行过程中,即显示小球运动轨迹过程中,并不能通过close或者右上角的关闭界面键来关闭程序;第二个程序是对第一个程序的缺陷进行了优化,它将小球的显示轨迹创建为程序的一个子线程,这样在小球显示轨迹过程中,可随时关闭界面。
实验2:结对编程练习:采用GUI界面设计以下程序,并创建程序归档文件。
设计一个100以内整数小学生四则运算练习程序,由计算机随机产生10道加减乘除练习题,学生输入答案,由程序检查答案是否正确,每道题正确计10分,错误不计分,10道题测试结束后给出测试总分;
将程序中测试练习题及学生答题结果输出到文件,文件名为test.txt。
实验总结:
通过本周的学习我学到了线程的概念,并且掌握了线程创建的两种技术,(1)用Thread类的子类创建线程(2)用Runnable()接口实现线程;
理解和掌握了线程的优先级属性及调度方法,学到了线程的七种状态。