概念区分:程序,进程,线程
程序:是可以让计算机执行某种操作的指令。存在磁盘上,由很多数据和一系列文件组成。
进程:程序运行起来就是一个进程。进程在系统分配的内存空间里。进程之间可以彼此通信,在不同电脑之间,在同一电脑上。
一个进程中有多个线程。
线程:一个进程中有多个线程,线程是独立运行的最小单位。
线程在CPU中执行,在使用线程时,自然会调用对象的属性,方法,常量,但这些属性,方法,常量都存在内存中,这时就由 缓存存储线程所需的数据。
线程操作缓存的数据,内存数据不变。线程没有独立存储空间,进程中所有线程公用进程的空间。
简单抽奖
思路:窗体 按钮 监听器 线程run
与画图板拖动鼠标画图不同,线程是可以实现自己动起来的效果,像下雪,小球运动,流星划过都可以通过线程做到。
实现线程的方法:
1.实现runnable接口:run()的方法,run方法是线程要执行的内容,启动线程调用start()方法
2.继承Thread类:含有run()方法,但调用线程,直接调用start()方法就可以,不能再调用run()方法了。其他方法请参考API
效果图
如果两图相同则中奖
源代码
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.imageio.IIOImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class DrawFrame extends JFrame {
// 抽奖思路:窗体 按钮 监听器 线程run
public static void main(String[] args) {
DrawFrame h = new DrawFrame();
h.draw();
}
private void draw() {
JFrame jf = new JFrame("抽奖1.0");
jf.setSize(500, 500);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.getContentPane().setBackground(Color.gray);
// 不可改大小
jf.setResizable(false);
JPanel p1 = new JPanel();
jf.add(p1);
JButton but = new JButton("Start");
JButton but2 = new JButton("End");
jf.add(but);
jf.add(but2);
java.awt.FlowLayout flow = new java.awt.FlowLayout();
jf.setLayout(flow);
// 标签
jf.setVisible(true);
Graphics g = jf.getGraphics();
//RUNNABLE r = new RUNNABLE(jf);这里注释的两行(这行和下一行)是第1种做法
//LotteryListener mouse = new LotteryListener(jf,r);
LotteryListener mouse = new LotteryListener(jf);
jf.addMouseMotionListener(mouse);
but.addActionListener(mouse);
but2.addActionListener(mouse);
}
}
我创建继承Thread的类的对象,有两种方法:
1.可以在创建窗口时就创建,再创建监听器对象时,以构造函数方法传过去。
//RUNNABLE r = new RUNNABLE(jf);这里注释的两行(这行和下一行)是第二钟做法
//LotteryListener mouse = new LotteryListener(jf,r);
2.如代码,先声明,再分配内存。
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class LotteryListener extends MouseAdapter implements ActionListener {
private JFrame jf;
private Graphics g;
private String str;
private RUNNABLE r;
// public LotteryListener(JFrame jf,RUNNABLE r) {
// this.jf = jf;
// this.r=r;
// g = jf.getGraphics();
// }
public LotteryListener(JFrame jf) {
this.jf = jf;
g = jf.getGraphics();
r = new RUNNABLE(jf);
}
public void mouseClicked(MouseEvent e) {}
public void actionPerformed(ActionEvent e) {//点击按钮
str = e.getActionCommand();
if ("Start".equals(str)) {
//start方法会自动调用run方法
r.start();
}
if ("End".equals(str)) {
r.setF(false);
//RUNNABLE r = new RUNNABLE(jf,flag);
int h=r.judge();
if(h==1){
JOptionPane.showMessageDialog(null,"恭喜您中奖了");
}else{
JOptionPane.showMessageDialog(null,"很遗憾您没有中奖");
}
}
}
}
方法1.的构造方法
// public LotteryListener(JFrame jf,RUNNABLE r) {
// this.jf = jf;
// this.r=r;
// g = jf.getGraphics();
// }
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class RUNNABLE extends Thread {
private Graphics g;
private JFrame jf;
private int m,n;
private boolean flag=true;
public RUNNABLE(JFrame jf) {
this.jf = jf;
//this.flag=flag;
g = jf.getGraphics();
}
public int judge(){
if(m==n){
return 1;
}else{
return 0;
}
}
public void run() {
while (flag) {
//画数字法
// g.setColor(Color.gray);
// g.fillRect(0, 0, 500, 500);
// Font font=new Font("宋体",Font.BOLD,70);
// g.setFont(font);
// Random rand=new Random();
// int number=rand.nextInt(10);
// g.setColor(Color.BLACK);
// g.drawString(""+number,200, 200);
// Random rand1=new Random();
// int number=rand1.nextInt(10);
// g.drawString(""+number,200, 200);
m= (int) (Math.random() * 10) ;
n= (int) (Math.random() * 10) ;
ImageIcon icon = new ImageIcon("F:\\卡通\\" +m+ ".jpg");
g.drawImage(icon.getImage(), 60, 150, 200, 200, null);
ImageIcon icon1 = new ImageIcon("F:\\卡通\\" +n + ".jpg");
g.drawImage(icon1.getImage(), 240, 150, 200, 200, null);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void setF(boolean flag2) {
flag=flag2;
}
}
第一次写的时候,只能开始不能停止,找了很久,在陈哥,熊哥帮助下才找到错误:
1.end按钮没加监听器;基础错误
2 private RUNNABLE r = new RUNNABLE(jf);这句话位置一直找不好。
3.调用start();方法就不用再调用run()方法。
以下是位置分析:
第一次放在这:报错----->原因是属性比方法先执行,也就是说我创建RUNNABLE对象时,jf还是空的。
private Graphics g;
private String str;
private RUNNABLE r = new RUNNABLE(jf);
public LotteryListener(JFrame jf) {
this.jf = jf;
g = jf.getGraphics();
}
第二次放在这:报错----->原因其实和错法1是一样的。
private Graphics g;
private String str;
public LotteryListener(JFrame jf) {
this.jf = jf;
g = jf.getGraphics();
}
public void mouseClicked(MouseEvent e) {}
private RUNNABLE r = new RUNNABLE(jf);
public void actionPerformed(ActionEvent e){..........}
第三次放在这:报错----->每一次点击都会重复创建对象,那么开始和结束不是一个线程操作的。
private Graphics g;
private String str;
public LotteryListener(JFrame jf) {
this.jf = jf;
g = jf.getGraphics();
}
public void mouseClicked(MouseEvent e) {}
public void actionPerformed(ActionEvent e){
private RUNNABLE r = new RUNNABLE(jf);
..........}