Java线程

1.有两种方法实现创建线程

a)继承Thread类

子类需要重载Thread类中的run()方法,这样子类就能作为线程启动了。
例如:

/*
 * MyThread.java
 * 
 * */

public class MyThread extends Thread {
    private int tickets = 10;

    public MyThread() {
        super();
        // TODO Auto-generated constructor stub
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i = 0; i<= tickets; i++){
            System.out.println("第" + i + "张票已卖出!"); 
        }
        System.out.println("票已卖完!");
    }   
}

使用的时候直接调用Thread类的start函数即可:

public class ThreadTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建线程
        MyThread thread1 = new MyThread();
        //启动线程
        thread1.start();
    }
}

输出结果如下:
这里写图片描述

b)实现Runnable接口

此类需要通过实现Runnable接口中run方法,这种方式创建线程的时候,需要把此类通过参数的形式传给Thread类来实现。
例如:

/*
 * MyRunnable.java
 * */
public class MyRunnable implements Runnable {

    private int tickets = 10;

    MyRunnable(){}

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i = 1;i <= 10; i++){
            if(tickets > 0){
                System.out.println("第" + tickets-- + "张票卖出!");
            }
        }
        System.out.println("票已卖完");
    }
}

线程的创建过程如下:


public class ThreadTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建线程
        //MyThread thread1 = new MyThread();
        //启动线程
        //thread1.start();

        //创建实现了Runnable接口的类实例
        MyRunnable r = new MyRunnable();
        //把创建的实例r做为参数传给Thread的构造函数,创建线程
        Thread thread2 = new Thread(r);
        //启动线程
        thread2.start();
    }
}

它运行结果如下:
这里写图片描述

2.多线程
为了更好的辨别输出结果属于哪个线程的,我们在线程类中增加一个线程id的输出信息,把输出语句替换为:

System.out.println("线程" + this.getId() +":第" + i + "张票已卖出!");

然后我们看下继承Thread的类来实现的多线程:

public class ThreadTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建线程1
        MyThread thread1 = new MyThread();
        //启动线程1
        thread1.start();

        //创建线程2
        MyThread thread2 = new MyThread();
        //启动线程2
        thread2.start();
    }
}

它的输出结果:
这里写图片描述
有结果可知:通过继承Thread类创建的每个线程对象中的run方法在处理自己的实例变量tickets
这时我们可能更需要的是多线程处理同一个数据tickets,这时就需要使用继承了Runnable的类来处理了。
这时可以直接如下创建线程:

public class ThreadTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyRunnable r = new MyRunnable();
        //把创建的实例r做为参数传给Thread的构造函数,创建线程
        Thread thread1 = new Thread(r);
        //启动线程
        thread1.start();

        Thread thread2 = new Thread(r);
        //启动线程
        thread2.start();
    }
}

来看下运行结果:
这里写图片描述

由结果可知:通过runnable实现的多线程可以实现多线程对同一资源的共享访问。

最后附上Thread.class中关于线程的说明:

/**
 * A <i>thread</i> is a thread of execution in a program. The Java
 * Virtual Machine allows an application to have multiple threads of
 * execution running concurrently.
 * <p>
 * Every thread has a priority. Threads with higher priority are
 * executed in preference to threads with lower priority. Each thread
 * may or may not also be marked as a daemon. When code running in
 * some thread creates a new <code>Thread</code> object, the new
 * thread has its priority initially set equal to the priority of the
 * creating thread, and is a daemon thread if and only if the
 * creating thread is a daemon.
 * <p>
 * When a Java Virtual Machine starts up, there is usually a single
 * non-daemon thread (which typically calls the method named
 * <code>main</code> of some designated class). The Java Virtual
 * Machine continues to execute threads until either of the following
 * occurs:
 * <ul>
 * <li>The <code>exit</code> method of class <code>Runtime</code> has been
 *     called and the security manager has permitted the exit operation
 *     to take place.
 * <li>All threads that are not daemon threads have died, either by
 *     returning from the call to the <code>run</code> method or by
 *     throwing an exception that propagates beyond the <code>run</code>
 *     method.
 * </ul>
 * <p>
 * There are two ways to create a new thread of execution. One is to
 * declare a class to be a subclass of <code>Thread</code>. This
 * subclass should override the <code>run</code> method of class
 * <code>Thread</code>. An instance of the subclass can then be
 * allocated and started. For example, a thread that computes primes
 * larger than a stated value could be written as follows:
 * <p><hr><blockquote><pre>
 *     class PrimeThread extends Thread {
 *         long minPrime;
 *         PrimeThread(long minPrime) {
 *             this.minPrime = minPrime;
 *         }
 *
 *         public void run() {
 *             // compute primes larger than minPrime
 *             &nbsp;.&nbsp;.&nbsp;.
 *         }
 *     }
 * </pre></blockquote><hr>
 * <p>
 * The following code would then create a thread and start it running:
 * <p><blockquote><pre>
 *     PrimeThread p = new PrimeThread(143);
 *     p.start();
 * </pre></blockquote>
 * <p>
 * The other way to create a thread is to declare a class that
 * implements the <code>Runnable</code> interface. That class then
 * implements the <code>run</code> method. An instance of the class can
 * then be allocated, passed as an argument when creating
 * <code>Thread</code>, and started. The same example in this other
 * style looks like the following:
 * <p><hr><blockquote><pre>
 *     class PrimeRun implements Runnable {
 *         long minPrime;
 *         PrimeRun(long minPrime) {
 *             this.minPrime = minPrime;
 *         }
 *
 *         public void run() {
 *             // compute primes larger than minPrime
 *             &nbsp;.&nbsp;.&nbsp;.
 *         }
 *     }
 * </pre></blockquote><hr>
 * <p>
 * The following code would then create a thread and start it running:
 * <p><blockquote><pre>
 *     PrimeRun p = new PrimeRun(143);
 *     new Thread(p).start();
 * </pre></blockquote>
 * <p>
 * Every thread has a name for identification purposes. More than
 * one thread may have the same name. If a name is not specified when
 * a thread is created, a new name is generated for it.
 * <p>
 * Unless otherwise noted, passing a {@code null} argument to a constructor
 * or method in this class will cause a {@link NullPointerException} to be
 * thrown.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祝云飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值