java基础:多线程(一)&GUI初步

lzy 666 0
摘要:

在一个进程中还可以有多个执行单元同时运行,这些执行单元被称为线程,线程是比进程更小的执行单元。

进程与线程

进程

一个程序的每一次运行称为进程

实际上,进程不是同时运行的,对于一个 CPU 而言,某个时间段只能运行一个程序,也就是只能执行一个进程。操作系统会为每个进程分配一段有限的 CPU 使用时间,CPU 在这段时间内执行某个进程,然后会在下一段时间切换到另一个进程中去执行。

线程

在一个进程中还可以有多个执行单元同时运行,这些执行单元被称为线程,线程是比进程更小的执行单元。

多线程指同一个程序进程内,多个线程同时执行。

java基础:多线程(一)&GUI初步

主线程

程序启动运行main时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建。

线程的创建与实现

1.通过继承Thread类

该类继承Thread类,创建这个类的对象时就可以产生一个新的线程。通过该类中重写run()方法、子类的实例对象使用start()方法启动线程。线程启动后,系统会自动调用 run() 方法。

Thread类:直接继承于Object,实现了Runnable接口。

package test_thread;
class Cat extends Thread
{
    public void run()
    {
        for(int i=0;i<55555;i++)
            if(i%10000==0)
                System.out.println("cattttttttttttttttttttt");
    }
}
class Dog extends Thread
{
    public void run()
    {
        for(int i=0;i<55555;i++)
            if(i%10000==0)
                System.out.println("doggggggggggggggggggggg");
    }
}
public class Test_Thread {
    public static void main(String[] args) {
        Cat c = new Cat();
        Dog d = new Dog();
        c.start();
        d.start();
    } 
}
/*
run:
cattttttttttttttttttttt
doggggggggggggggggggggg
cattttttttttttttttttttt
doggggggggggggggggggggg
doggggggggggggggggggggg
doggggggggggggggggggggg
cattttttttttttttttttttt
doggggggggggggggggggggg
doggggggggggggggggggggg
cattttttttttttttttttttt
cattttttttttttttttttttt
cattttttttttttttttttttt
成功构建 (总时间: 0 秒)
*/

2.越过Thread类直接实现Runnable接口

由于Java中只支持单继承,一个类如果继承了某个父类就不能再继承 Thread 类了。为了克服弊端,Thread 类提供了另一个构造方法 Thread(Runnable target),该方法中,Runnable 是一个接口,它只有一个 run() 方法。

当应用时, 需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象 ,通过new Thread(c).start启动进程,此时该实例对象作为Thread构造方法的参数。

package test_thread;
class Cat implements Runnable
{
    public void run()
    {
        for(int i=0;i<55555;i++)
            if(i%10000==0)
                System.out.println("cattttttttttttttttttttt");
    }
}
class Dog implements Runnable
{
    public void run()
    {
        for(int i=0;i<55555;i++)
            if(i%10000==0)
                System.out.println("doggggggggggggggggggggg");
    }
}
public class Test_Thread {
    public static void main(String[] args) {
        Cat c = new Cat();
        Dog d = new Dog();
        new Thread(c).start();
        new Thread(d).start();
    } 
}
/*
run:
cattttttttttttttttttttt
doggggggggggggggggggggg
cattttttttttttttttttttt
doggggggggggggggggggggg
cattttttttttttttttttttt
doggggggggggggggggggggg
doggggggggggggggggggggg
cattttttttttttttttttttt
doggggggggggggggggggggg
doggggggggggggggggggggg
cattttttttttttttttttttt
cattttttttttttttttttttt
成功构建 (总时间: 0 秒)
*/

线程的生命周期与状态

生命周期状态图

java基础:多线程(一)&GUI初步

基本状态

–诞生状态:线程刚刚被创建

–就绪状态:线程已准备好运行,执行start方法

–运行状态:处理机分配给了线程,线程正在运行

–阻塞状态:等待其他线程释放互斥资源时

–休眠状态:执行sleep方法而进入休眠

–死亡状态:线程已完成或退出

线程优先级

(没听懂,有空再更)

常用方法

Thread()

构造一个新的线程对象,默认名为Thread-n,n是从0开始递增的整数。

Thread(String name)

构造一个新的线程对象,并同时指定线程名。

getName()

返回此线程的名称。

isAlive()

测试这个线程是否还处于活动状态。

活动状态就是线程已经启动且尚未终止。线程处于正在运行或准备运行的状态。

sleep(long millis)

使当前正在执行的线程以指定的毫秒数“休眠”(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。

interrupt()

只是给另一个线程发送一个中断信号,到底该线程是否处理中断信号由该线程自行处理。

interrupted() 和isInterrupted()

interrupted():测试当前线程是否已经是中断状态,执行后具有将状态标志清除为false的功能。

isInterrupted(): 测试线程Thread对相关是否已经是中断状态,但不清楚状态标志。

setName(String name)

将此线程的名称更改为等于参数 name 。

join()

在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。

join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。

yield()

yield()方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU时间。注意:放弃的时间不确定,可能一会就会重新获得CPU时间片。

线程同步

当多个线程需要处理同一个数据时,需要做同步处理。

理解成多线程运行相当于不同道路的车同时在开,然后当他们同时走到一个窄路口的时候(就是调用同一个方法的时候 ),让车一个个过。——来自祥硕哥哥的理解

措施: 把synchronized关键字加在互斥的方法上 , 保证一段代码在多线程执行时是互斥的

GUI初步

通过多线程技术(其实没用),使用sleep()方法,实现进度条的动态更新效果。

class Controller extends Thread
{
    JProgressBar jpb;
    Controller(JProgressBar jpb)
    {
        this.jpb=jpb;
    }
    public void run()
    {
        for(int i=0;i<=jpb.getMaximum();i++)
        {
            try {
                jpb.setValue(i);
                sleep(50);
            } catch (InterruptedException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
new Controller(jindu).start();
/*启动线程,可以放在窗体的构造方法中运行即启动,也可以放在鼠标、键盘事件中启动。*/
java基础:多线程(一)&GUI初步

发表评论 取消回复
表情 图片 链接 代码

分享