JAVA线程初解

来源:互联网 发布:大数据的看法 编辑:程序博客网 时间:2024/06/06 11:00

在之前的代码中,我们的代码都是从main方法开始,从上往下依次进行的,也就是说如果上面的代码如果没有运行结束,那么后面的代码是运行不了的,在代码量较小时,还没有体现出这种方式的弊端,但如果你的代码特别的多,那么这种方式所耗费的时间是很多的,针对这种情况java引入了一个新的概念,这就是线程。
实现现成的方法有两种:

  • 继承Thread类,实现它的run()方法;
  • 实现Runnable接口,实现它的run()方法。

在run()方法中写入你线程中想要运行的代码。
启用一个线程的办法就是调用Thread类的start()方法,而实现了Runnable接口的类想要开启线程就需要借用Thread的构造方法

public Thread(Runnable target)

,传入一个Runnable接口的实现类去new一个Thread,从而调用它的start()方法。调用start()方法后有两个作用:一是开启了新线程,而是运行了县城里的run()方法。
在这里要介绍一些常用的线程方法;

线程休眠(Thread.sleep(毫秒值))线程名称(setName(),getName();)线程的调度及优先级setPriority(10)(注意默认值是5,区间在1-10之间)

这里附上代码说明:

package com.thz_02;//由于Runnable接口没有start、setName、getName方法,//所以在这里调用Thread中的静态的currentThread方法返回当前调用的线程对象public class MyRunnable implements Runnable{    @Override    public void run() {        for (int i = 0; i < 100; i++) {            //休眠100毫秒            try {                Thread.sleep(100);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName()+i);        }    }}
package com.thz_03;import com.thz_02.MyRunnable;//设置优先级public class Test {    public static void main(String[] args) {        //创建三个线程对象,由于此时的线程对象是实现了Runnable接口的对象,没有start和setName、getName方法        MyRunnable mr1 = new MyRunnable();        MyRunnable mr2 = new MyRunnable();        MyRunnable mr3 = new MyRunnable();        //创建带接口的Thread对象        Thread t1 = new Thread(mr1);        Thread t2 = new Thread(mr2);        Thread t3 = new Thread(mr3);        //起名字        t1.setName("张三");        t2.setName("李四");        t3.setName("王五");        //查看优先级,默认为5        System.out.println("mt1的优先级是"+t1.getPriority());        System.out.println("mt2的优先级是"+t2.getPriority());        System.out.println("mt3的优先级是"+t3.getPriority());        //设置优先级        /*优先级为1-10         * 不然会运行时异常,报错:IllegalArgumentException         * 表明向方法传递了一个不合法或不正确的参数         */        t1.setPriority(1);        t2.setPriority(5);        t3.setPriority(10);        //再次查看优先级        System.out.println("mt1设置后的优先级是"+t1.getPriority());        System.out.println("mt2设置后的优先级是"+t2.getPriority());        System.out.println("mt3设置后的优先级是"+t3.getPriority());        //开始线程        t1.start();        t2.start();        t3.start();    }}

但是如果实现了多线程,那么就又会牵扯一个新的问题,这就是线程安全问题。这里就要提一下多线程案例中的卖票案例:

卖票案例:
1、用多线程去实现多个窗口卖票的功能;
2、用线程休眠去实现窗口卖票间隙的问题;

这里附上代码:

package com.thz_05;//实现了Runnable接口的卖票public class TicketRunnable implements Runnable{    int ticket = 100;    @Override    public void run() {        //while true循环        while(true){            try {                Thread.sleep(100);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            if(ticket>0){                System.out.println("这是"+Thread.currentThread().getName()+"卖的第"+ticket--+"张票");            }        }    }}
package com.thz_05;/* * 出现问题: * 1、卖了重复的票 * 2、卖了第0和-1张票 * 线程不安全 */public class Test {    public static void main(String[] args) {        //创建三个线程对象        TicketRunnable tr1 = new TicketRunnable();        TicketRunnable tr2 = new TicketRunnable();        TicketRunnable tr3 = new TicketRunnable();        Thread t1 = new Thread(tr1);        Thread t2 = new Thread(tr2);        Thread t3 = new Thread(tr3);        //启动线程        t1.start();        t2.start();        t3.start();    }}

这是继承了Thread类的卖票模拟:

package com.thz_04;//继承Thread卖票/* * 1、3个窗口卖100张票--3个线程 * 2、窗口一直开放--while true循环 * 3、卖票有间隔时间--线程休眠 * 4、票据不重复 */public class TicketThread extends Thread{    static int ticket = 100;    public void run() {            while(true){                //线程休眠,会报错,抓一下                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                if(ticket>0){                    System.out.println("这是"+this.getName()+"卖的第"+ticket--+"张票");                }else{                    break;                }        }    }}
package com.thz_04;/* * 出现的问题:卖出重复的票 * 线程不安全 *///继承Thread卖票/** 1、3个窗口卖100张票--3个线程* 2、窗口一直开放--while true循环* 3、卖票有间隔时间--线程休眠* 4、票据不重复*/public class Test {    public static void main(String[] args) {        //3个窗口卖100张票--3个线程        TicketThread tt1 = new TicketThread();        TicketThread tt2 = new TicketThread();        TicketThread tt3 = new TicketThread();        tt1.setName("窗口一");        tt2.setName("窗口二");        tt3.setName("窗口三");        //窗口一直开放--while true循环        tt1.start();        tt2.start();        tt3.start();    }}

以上的代码都是线程不安全的。关于线程安全的相关问题请看下一章:JAVA线程安全相关