java多線程編程實(shí)現(xiàn)下雪效果
沒有直接采用繼承Thread類或者繼承Runnable的接口來實(shí)現(xiàn)多線程,而是使用了匿名內(nèi)部類。
要導(dǎo)入的類:
import javax.swing.*; import java.awt.*;
1.定義SowPanel類,繼承JPanel類,這個(gè)類有兩個(gè)整型數(shù)組成員,用來保存雪花起始位置。在構(gòu)造函數(shù)中為數(shù)組賦初值;重寫父類的paint()方法;定義一個(gè)啟動(dòng)多線程的startSnow()方法。
class SnowPanel extends JPanel
{
//定義整型數(shù)組,存儲(chǔ)雪花坐標(biāo)
private int[] x=new int[300];
private int[] y=new int[300];
public SnowPanel()
{
//設(shè)置背景為黑色
setBackground(Color.black);
//用隨機(jī)數(shù)初始化雪花坐標(biāo)
for(int i=0;i<x.length;i++)
{
x[i]=(int)(Math.random()*800);
y[i]=(int)(Math.random()*600);
}
}
public void paint(Graphics g)
{
//繼承父類畫的方法
super.paint(g);
//設(shè)置顏色為白色
g.setColor(Color.white);
//利用循環(huán)畫出多個(gè)雪花
for(int i=0;i<x.length;i++)
{
g.drawString("*",x[i],y[i]);
}
}
//定義一個(gè)方法啟動(dòng)多線程,并使用匿名內(nèi)部類
public void startSnow()
{
new Thread()
{
public void run()
{
while(true)
{
for(int i=0;i<y.length;i++)
{
//坐標(biāo)下移
y[i]++;
//檢查是否越界
if(y[i]==600)
y[i]=0;
//重繪
repaint();
}
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
}
2.定義ShowFrame類,繼承Jframe 類。在構(gòu)造方法中設(shè)置窗口的顯示屬性,并創(chuàng)建ShowPanel對(duì)象,添加到窗口中。
class SnowPanel extends JPanel
{
//定義整型數(shù)組,存儲(chǔ)雪花坐標(biāo)
private int[] x=new int[300];
private int[] y=new int[300];
public SnowPanel()
{
//設(shè)置背景為黑色
setBackground(Color.black);
//用隨機(jī)數(shù)初始化雪花坐標(biāo)
for(int i=0;i<x.length;i++)
{
x[i]=(int)(Math.random()*800);
y[i]=(int)(Math.random()*600);
}
}
public void paint(Graphics g)
{
//繼承父類畫的方法
super.paint(g);
//設(shè)置顏色為白色
g.setColor(Color.white);
//利用循環(huán)畫出多個(gè)雪花
for(int i=0;i<x.length;i++)
{
g.drawString("*",x[i],y[i]);
}
}
//定義一個(gè)方法啟動(dòng)多線程,并使用匿名內(nèi)部類
public void startSnow()
{
new Thread()
{
public void run()
{
while(true)
{
for(int i=0;i<y.length;i++)
{
//坐標(biāo)下移
y[i]++;
//檢查是否越界
if(y[i]==600)
y[i]=0;
//重繪
repaint();
}
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
}
3.運(yùn)行效果圖片(此為靜態(tài)圖):

疑問:發(fā)現(xiàn)其他的不改變,繼承Frame、Panel和繼承JFrame、Jpanel的運(yùn)行效果是不同的,前者顯示的下雪場(chǎng)景總是有閃爍的感覺;后者則沒有閃爍,個(gè)人感覺后者效果更好些。
接下來我們來看個(gè)例子
這里我們做一個(gè)完整的例子來說明線程產(chǎn)生的方式不同而生成的線程的區(qū)別:
package debug;
import java.io.*;
import java.lang.Thread;
class MyThread extends Thread{
public int x = 0;
public void run(){
System.out.println(++x);
}
}
class R implements Runnable{
private int x = 0;
public void run(){
System.out.println(++x);
}
}
public class Test {
public static void main(String[] args) throws Exception{
for(int i=0;i<10;i++){
Thread t = new MyThread();
t.start();
}
Thread.sleep(10000);//讓上面的線程運(yùn)行完成
R r = new R();
for(int i=0;i<10;i++){
Thread t = new Thread(r);
t.start();
}
}
}
上面10個(gè)線程對(duì)象產(chǎn)生的10個(gè)線程運(yùn)行時(shí)打印了10次1。下面10個(gè)線程對(duì)象產(chǎn)生的10個(gè)線程運(yùn)行時(shí)打印了1到10。我們把下面的10個(gè)線程稱為同一實(shí)例(Runnable實(shí)例)的多個(gè)線程。
相關(guān)文章
Spring5中SpringWebContext方法過時(shí)的解決方案
這篇文章主要介紹了Spring5中SpringWebContext方法過時(shí)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
springboot集成redis實(shí)現(xiàn)簡(jiǎn)單秒殺系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了springboot集成redis實(shí)現(xiàn)簡(jiǎn)單秒殺系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
淺析Java中ConcurrentHashMap的存儲(chǔ)流程
ConcurrentHashMap技術(shù)在互聯(lián)網(wǎng)技術(shù)使用如此廣泛,幾乎所有的后端技術(shù)面試官都要在ConcurrentHashMap技術(shù)的使用和原理方面對(duì)小伙伴們進(jìn)行360°的刁難,本文詳細(xì)給大家介紹一下ConcurrentHashMap的存儲(chǔ)流程,需要的朋友可以參考下2023-05-05
使用logback實(shí)現(xiàn)按自己的需求打印日志到自定義的文件里
這篇文章主要介紹了使用logback實(shí)現(xiàn)按自己的需求打印日志到自定義的文件里,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
mybatis如何實(shí)現(xiàn)saveOrUpdate
這篇文章主要介紹了mybatis如何實(shí)現(xiàn)saveOrUpdate問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
Java如何把數(shù)組轉(zhuǎn)換為ArrayList
這篇文章主要介紹了Java如何把數(shù)組轉(zhuǎn)換為ArrayList,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01

