java 多线程基础(1)

Thread 用法

public class MyThread extends Thread{
    private String name;    
    public MyThread(String name) {
        this.name = name;
    }
    public void run(){
        for (int i = 0; i < 5; i++) {
            try {
                System.out.println("--------------"+i+"-----"+this.name);
                sleep((int) Math.random() * 10);
            }
            catch (InterruptedException e) {                
                e.printStackTrace();                
            }
        }
    }
}


public class TestThread {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread("123");
        MyThread myThread2 = new MyThread("456");
        myThread1.start();
        myThread2.start();      
        /*MyRunnable myRunnable1 = new MyRunnable("123");
        MyRunnable myRunnable2 = new MyRunnable("456");     
          new Thread(myRunnable1).start();
          new Thread(myRunnable2).start();*/        
    }
}

注意: 调用start() 方法之后 程序不会马上执行,线程的状态变为可运行状态(Runnable),什么时候运行取决于系统
多线程的执行结果是乱序的,每次执行的顺序多是随机的
但是 start() 方法重复调用的话 ,会抛出异常, java.lang.IllegalThreadStateException

        MyThread myThread1 = new MyThread("123");
        MyThread myThread2 = myThread1;
        myThread1.start();
        myThread2.start();

        原因是 Thread 有一个判断

        private volatile int threadStatus = 0;

    public synchronized void start() {

        if (threadStatus != 0)
            throw new IllegalThreadStateException();


        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }
主要原因是 myThread1 中的 threadStatus 对于 myThread2 是共享的(因为 volatile) 
在JM 中每个状态都会去判断  threadStatus 的值,因为 threadStatus 在1中初始化为 0 ,所以在2中每次执行都会报错。

Thread 是 继承 Runable

public class Thread implements Runnable

Runnable

public class MyRunnable implements Runnable {

    private String name;

    public MyRunnable(String name) {

        this.name = name;
    }
    @Override
    public void run() {

        for (int i = 0; i < 5; i++) {
            try {
                System.out.println("--------------"+i+"-----"+this.name);
                Thread.sleep((int) Math.random() * 10);
            }
            catch (InterruptedException e) {

                e.printStackTrace();

            }
        }

    }


}


public class TestThread {

    public static void main(String[] args) {
        /*MyThread myThread1 = new MyThread("123");
        MyThread myThread2 = new MyThread("456");
        myThread1.start();
        myThread2.start();*/

        MyRunnable myRunnable1 = new MyRunnable("123");
        MyRunnable myRunnable2 = new MyRunnable("456");

          new Thread(myRunnable1).start();
          new Thread(myRunnable2).start();

    }
}

为什么要这样才能执行那?

先看Runnable 接口 ,注意我这里说的是接口

代码:

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

注释很简单 ,当你用Runnable创建一个线程的时候,必须实现 run()方法。

而在Thread 中

    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }
     public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    Thread(Runnable target, AccessControlContext acc) {
        init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
    }
init 是Thread的初始化方法,在这里 就是 为什么 要去 new Thread(myRunnable1).start(); 这样启动一个线程。

Thread 和Runnable 的区别

总结: Thread是一个类,只能单继承,但是Runnable是接口,可以多继承,适合资源共享,增加程序的健壮性,代码可以被多个线程共享,代码和数据独立

线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类

mian方法也是一个线程,java程序中每次执行至少会开启2个线程,一个是main线程,一个是垃圾回收线程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值