产生变化),复选框的个人爱好。可输入多组用户信息,然后通过操作菜单的查询字菜单项,在查询窗口中显示前面输入的所有用户信息。
第八章 多线程机制
1、程序是描述应用软件执行的蓝本的一段静态代码。 进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。线程是比进程更小的执行单位,一个进程在其执行过程中,可以产生多个线程,形成多条执行线索。每条线索,即每个线程也有它自身的产生、存在和消亡的过程,也是一个动态的概念。 Java的多线程就是在操作系统每次分时给Java程序一个时间片的CPU时间内,在若干个独立的可控制的线程之间切换。 2、用Thread类或子类创建线程对象。编写Thread类的子类时,需要重写父类的run方法,其目的是规定线程的具体操作 。
public class Clerk extends Thread { public Clerk(String name) { super(name); } @Override public void run() { super.run(); // 添加具体的工作代码 } }
3、实现Runnable接口。 构造方法:Thread(Runnable target)形式参数为Runnable类型的接口,在创建线程对象时实际参数为Runnable接口类的实例对象,作为所创线程的目标对象。当线程享用CPU资源,目标对象就会自动调用接口中的run方法(接口回调)。 public class Clerk implements Runnable{ @Override public void run() { // 添加具体的工作代码 } }
Thread clerk=new Thread(new Clerk()); 4、线程的常用方法:
start() 作用:线程调用该方法将启动线程,使之从新建状态进入就绪队列排队,一旦轮到它来享用CPU资源时,就可以脱离创建它的线程独立开始自己的生命周期了。 格式:创建线程对象.start(); run() 作用:用来定义线程对象被调度之后所执行的操作,都是系统自动调用而用户程序不得引用的方法。注:系统的Thread类中,run()方法没有具体内容,所以用户程序需要创建自己的Thread类的子类,并重写run()方法来覆盖原来的run()方法。当run方法执行完毕,线程就变成死亡状态。
currentThread()特点:Thread类中的类方法,可以用类名调用。作用:返回当前正在使用CPU资源的线程。 格式:Thread.currentThread()
sleep(int millsecond)作用:线程运行期间执行sleep方法来使自己放弃CPU资源,休眠一段时间。休眠时间的长短由参数millsecond决定,以毫秒为单位计算休眠时间。如果线程在休眠时被打断JVM就抛出Interrupted Exception异常。所以必在try~catch语句块中调用sleep方法。 格式:Thread.sleep(int millsecond);
interrupt() intertupt方法用来“吵醒”休眠的线程。作用:当一些线程调用sleep方法处于休眠状态时,一个正占有CPU资源的线程可让休眠的线程调用interrupt 方法“吵醒”自己 。 格式:休眠线程.interrupt();
5、线程同步:当几个线程都需要调用一个同步方法(使用关键字synchronized修饰的方法) ,称为线程同步.
同步机制:当一个线程A使用一个synchronized修饰的方法时,其他线程再想使用这个方法时就必须等待,直到线程A 使用完该方法(除非线程A使用wait主动让出CPU资源)。 6、挂起:所谓挂起一个线程就是让线程暂时让出CPU的使用权限,暂时停止执行,但停止执行的持续时间不确定,因此不能使用sleep方法暂停线程。挂起一个线程需使用wait方法,即让准备挂起的线程调用 wait 方法,主动让出CPU的使用权限. 7、恢复线程
8、在其它线程占有CUP资源期间,让挂起的线程的目标对象执行notifyAll()方法,使得挂起的线程继续执行;如果线程没有目标对象,为了恢复该线程,其它线程在占有CUP资源期间,让挂起的线程调用notifyAll()方法,使挂起的线程继续执行。
9、计时器线程Timer:作用:需要周期性执行的操作,可以通过计时器来进行处理
构造方法:Timer(int a, Object b)创建一个计时器 参数a的单位是豪秒,确定计时器每隔a 毫秒\震铃\一次,参数b是计时器的监视器。
震铃事件为ActinEvent 类型,当该事件发生时,监视器就会监视到这个事件,然后执行方法:actionPerformed(Actionevent e) 使用Timer类的start()方法启动计时器即启动线程。使用stop()方法停止计时器,即挂起线程,使用restart()方法重新启动计时器,即恢复线程。
10、线程联合:一个线程A在占有CUP资源期间,可以让其它线程调用join()和本线程联合。如果线程A在占有CUP资源期间一旦联合B线程,那么A线程将立刻中断执行,一直等到它联合的线程B执行完毕,A线程再重新排队等待CUP资源,以便恢复执行。 11、例子
public class ThreadTest { public static void main(String args[]){ //调用所建立的线程类,并创建线程对象 LHand l; RHand r; l=new LHand(); r=new RHand(); //调用start方法运行线程对象 r.start(); l.start(); //编写主线程代码 for(int i=0;i<10;i++){ System.out.println(\ } } }
class LHand extends Thread{ public void run(){ for(int i=0;i<10;i++){ System.out.println(\ } } }
class RHand extends Thread{ public void run(){ for(int i=0;i<10;i++){ System.out.println(\ }
} }
public class runnableTest { public static void main(String[] args) { // TODO Auto-generated method stub Hand h=new Hand(); //调用start方法运行线程对象 h.l.setPriority(10); h.l.start(); h.r.start(); //编写主线程代码 } }
class Hand implements Runnable{ Thread l,r; public Hand(){ l=new Thread(this); r=new Thread(this); l.setName(\ r.setName(\ } public void run(){ if(Thread.currentThread()==l){ System.out.println(l.getName()+\ System.out.println(l.isAlive()); try { Thread.sleep(1000*60); } catch (InterruptedException e) { // TODO Auto-generated catch block System.out.println(l.getName()+\被叫醒了!\ } System.out.println(l.getName()+\开始听课!\ }else if(Thread.currentThread()==r){ for(int i=0;i<3;i++){ System.out.println(\上课\ try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block } } l.interrupt(); } } }
//线程同步
public class threadSY { public static void main(String[] args) {
// TODO Auto-generated method stub FM f=new FM(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(500, 500); f.setVisible(true); } }
class FM extends JFrame implements Runnable,ActionListener{ int money=100; int weekDay; JButton bStart; JTextArea tj1,tj2; Thread kj,cn; public FM(){ super(\线程同步示例\ bStart=new JButton(\开始演示\ bStart.addActionListener(this); kj=new Thread(this); cn=new Thread(this); tj1=new JTextArea(); tj2=new JTextArea(); ScrollPane s1=new ScrollPane(); s1.setSize(100,150); s1.add(tj1); ScrollPane s2=new ScrollPane(); s2.setSize(100,150); s2.add(tj2); Container c=this.getContentPane(); FlowLayout f=new FlowLayout(); f.setHgap(30); c.setLayout(f); c.add(bStart); c.add(s1); c.add(s2); } @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub if(!cn.isAlive()){ cn=new Thread(this); kj=new Thread(this); cn.start(); kj.start(); } } @Override public void run() { // TODO Auto-generated method stub if(Thread.currentThread()==kj||Thread.currentThread()==cn){ for(int i=1;i<=3;i++){
weekDay=i; cq(30); } } } public synchronized void cq(int number){ if(Thread.currentThread()==kj){ tj1.append(\今天是星期\ for(int i=0;i<3;i++){ money=money+number; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block tj1.append(\帐上有\ } } }else if(Thread.currentThread()==cn){ } } 12、实验
(1)编写一个应用程序,除主线程外还有两个线程,一个负责模拟红色按钮从(10,60)运动到(100,60),另一个负责模拟一个绿色按钮从(100,60)运动到(100,300)。
(2)三人排队买票,甲、乙、丙,售票员只有三张5元,电影票5元一张。甲拿20元一张的人民币排在乙的前面买票,乙排在丙前面拿一张10元人民币买票,丙拿一张5元人民币买票。(售票方法为同步对象,在售票方法中分别对接受到五元,十元和二十元的几种货币作区分,对于无法找零的情况,让当时运行的县城被挂起,知道有合适找零金额再将其唤醒。) (3)编写一个应用程序,在主线程中创建三个线程:“运货司机”“装运工”“仓库管理员”。要求线程“运货司机”占有CPU资源后立刻联合线程“装运工”,而“装运工”占有资源后立刻联合线程“仓库管理员”,打开仓库搬运货物,然后装成,运走。(采用线程联合的概念)
第九章 输入输出流
1、File类:代表了磁盘上的一个文件或一个目录,该类对象主要用来获取文件本身的一些信息,例如文件所在的目录、长度、读写权限等。注:File不涉及对文件的读写操作。 2、I/O流:流就是一个传送有序的字节序列,是传输在数据节点和程序间的连接通道上的字节序列。换句话说,流就是对输入数据源和输出目的地的抽象表示。
按照传输单位分类:字节流:数据的处理以字节为基本单位InputStream(字节输入流)OutputStream(字节输出流);字符流,用于字符数据的处理 Reader(字符输入流)Writer(字符输出流)
3、流编程的步骤:创建节点流对象;创建节点流;利用过滤流对节点流进行封装;传递数据;关闭流 (关闭外层流) 4、例子
//字节型输入输出流的使用 public class StreamTest {
public static void main(String args[]) { int b;
byte tom[]=new byte[25];

