精华内容
下载资源
问答
  • Java中启动线程有两种方式,继承Thread类以及实现接口Runnable,由于Java无法... start():通过该方法启动线程的同时也创建了一个线程,真正实现了多线程,这是无需等待run()方法中的代码执行完毕就可以直接执行下面

    Java中启动线程有两种方式,继承Thread类以及实现接口Runnable,由于Java无法实现多重继承,故经常通过实现接口Runnable来创建线程。但是无论哪种方式创建都可以通过start()和run( )方法来启动线程,下面就来介绍一下两者的区别。

         start():通过该方法启动线程的同时也创建了一个线程,真正实现了多线程,这是无需等待run()方法中的代码执行完毕就可以直接执行下面的代码,通过start创建的线程处于可运行状态,当得到CPU时间片后就会执行其中的run方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
    
        run():通过run方法启动线程其实就是调用一个类中的方法,并没有创建一个线程,程序中还是只有主线程,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
    
        下面是两种创建线程的代码示例:
    

    通过继承Thread类

    package com.Test.Tread;

    public class ThreadDemo02 extends Thread{
    public void run(){
    System.out.println(“线程启动!”);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
       ThreadDemo02 thread = new ThreadDemo02();
       thread.start();
    }
    

    }

    通过实现Runnable接口

    package com.Test.Tread;

    public class ThreadDemo03 implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("线程启动02");
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
       Thread thread01 = new Thread(new ThreadDemo03());
       thread01.start();
    }
    

    }

    展开全文
  • 线程之间的执行是相互独立的,哪一个线程优先执行取决于OS的调度 线程的创建方式: 实现Runnable接口: ...调用thread实例的start,启动线程; 普通方式 package ThreadDemo; class Thread1 i...
    线程之间的执行是相互独立的,哪一个线程优先执行取决于OS的调度

    线程的创建方式:

    实现Runnable接口:

    • 创建自定义类并实现runnable接口,且实现接口中的run方法;
    • 实例化自定义的类;
    • 将自定义类的实例作为参数传给Thread类,创建thread实例;
    • 调用thread实例的start,启动子线程;
    普通方式
    package ThreadDemo;
    
    class Thread1 implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"子线程");
        }
    }
    public class RunnableDemo {
        public static void main(String[] args) {
              Thread1 thread1=new Thread1();
              Thread thread=new Thread(thread1);
              thread.start();
        }
    }
    
    
    lambda表达式呈现:
    public class RunnableDemo {
        public static void main(String[] args) {
              Thread thread=new Thread(()->{
                  System.out.println(Thread.currentThread().getName()+"子线程");
              });
              thread.start();
        }
    }
    

    继承Thread类创建线程

    • 创建自定义类并继承Thread类,并且重写run方法;
    • 实例化自定义类
    • 通过实例化对象调用start方法来创建线程;
    package ThreadDemo;
    
    class Thread1 extends Thread{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"子线程");
        }
    }
    public class RunnableDemo {
        public static void main(String[] args) {
              Thread1 thread1=new Thread1();
              thread1.start();
        }
    }
    
    

    实现Callable接口:线程池提供的一种创建线程的方式;

    • 实现Callable接口,并实现它的call方法;
    • 创建线程池(Executors工具类提供的方法创建线程池);
    • 创建Callable接口实现类的实例;
    • 将实例对象通过线程池的submit(提交)方法提交给线程池进而创建新的线程;
    package ThreadDemo;
    
    import java.util.concurrent.*;
    
    class Thread2<T> implements Callable<T> {
        @Override
        public T call() throws Exception {
            System.out.println(Thread.currentThread().getName());
            return null;
        }
    }
    public class RunnableDemo {
        public static void main(String[] args) {
            ExecutorService executor= Executors.newSingleThreadExecutor();
             Thread2<Integer> thread2=new Thread2();
             Future<Integer>future= executor.submit(thread2);
            try {
                Integer integer=future.get();
                future.cancel(true);
                //用于取消异步的任务,它传入一个boolean类型的参数,传入true会中断线程停止任务,
                // 而传入false则会让线程正常执行至完成,并返回false。 
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    线程操作的相关方法介绍:

    • void start(): 启动一个新的线程,start方法必须是子线程第一个调用的方法,start方法不能够重复调用(否则会抛异常),新线程会调用runnable接口提供的run方法;
    • void run(): run方法是子线程的执行体,子线程从进入run方法开始直至run方法结束,意味着子线程的任务执行结束;在主线程直接调用run方法是不能创建子线程的,只是普通方法调用;
    • yield(): 让步或者暂停,Thread类的静态方法。让正在执行的线程停止或者让步,让给优先级较高的线程获取CPU的执行权(不一定会让出CPU执行权,如等待的线程优先级较低或者当前线程只有一个线程在执行时,那么当前线程又会立即获取CPU的执行权)
      thread.yield() == 》 thread != 正在执行的线程 ==》 静态方法通过实例调用,但是跟实例没有任何关系;
    • static native void sleep(long millis) throws InterruptedException: sleep方法作用是让线程进行休眠,即让线程阻塞住,Thread类提供的静态方法,会抛出InterruptedException异常;
    • join(): 等待线程执行结束才继续执行,会抛出InterruptedException异常;
      假如在a线程中b线程进行 b.join() 调用,那么a线程执行结束才能继续执行,控制多线程按照次序执行;
    • interrupt(): 中断方法,底层调用native方法,native方法的作用是对特定标识位做出修改,主要作用于线程:运行中线程,阻塞线程(sleep/join)
      运行中线程: interrupt方法仅仅是对标志位做了修改,其它没有影响;
      阻塞线程: interrupt方法对标志位做了修改,另阻塞中的线程感知到标志位做了修改,就会中断当前的阻塞状态,抛出InterruptedException异常;
    • boolean isInterrupted(): 判断是否发生了中断操作,true表示发生了中断,false 表示未发生中断;
    • setPriority(int newPriority): 设置线程优先级,优先级分为10级,优先级数字越大,即优先级越高,优先级越高,被优先调用的概率会增大;但是不一定会被优先执行,还是要看本地操作系统的
      MIN_PRIORITY=1; 最小优先级;
      NORM_PRIORITY=5 ; 默认优先级;
      MAX_PRIORITY=10 ; 最大优先级;
    • int getPriority(): 返回当前程序的优先级;
    • setDaemon(boolean on): 设置守护线程,true:设置为守护线程,false:用户线程; 线程不进行设置,默认为用户线程;
    • boolean isDaemon(): 判断当前线程是否为守护线程;

    守护线程:

    脱离于控制终端,作为提供通用服务的线程存在。

    用户线程和守护线程的区别:

    • 生命周期:守护线程的生命周期是依赖于用户线程,当有用户线程存在,守护线程就会存活,当没有用户线程存在,那么守护线程也会随之消亡。垃圾回收是有单独线程来处理的,负责垃圾回收的线程就是守护线程;

    为什么sleep和yield方法是静态的:

    sleep分析:为什么不设计成非静态的,当实例调用时,该实例休眠 ?

    • 如果是实例方法,就可以实现在一个线程里随时让其它线程在执行中休眠,而且这种休眠是不放弃锁的。那么这种简单粗暴就很容易引起混乱,因此目前这种机制其实就是一种限制:你可以选择给自己吃安眠药,而不能随便给正在工作的别人吃安眠药;

    • 线程和实例并不是对等的,不是一个线程是一个实例,是你创建的实例继承了Thread或者Runable,实现了run(),并调用start()的时候能执行多个线程,实例还是一个,线程却是多个。所以实例休眠线程就休眠了这个假设不成立。

    yield分析:

    yield()是建议线程调度程序从当前线程中让出CPU时间给别的线程,这是一种总体调度,不是仅仅和某个线程相关的,而是和每个线程都有关。线程和人不一样,不是当前线程让了,别的线程就会来抢,是需要调度程序来调度的。

    关于sleep()方法和yield()方法的区别如下:

    • sleep()方法暂停当前线程后,会给其他线程执行机会,不会理会其他线程的优先级;但yield()方法只会给优先级相同,或优先级更高的线程执行机会。

    • sleep()方法会将线程转入阻塞状态,直到经过阻塞时间才会转入就绪状态;而yield()方法不会将线程转入阻塞状态,它只是强制当前线程进入就绪状态。因此完全有可能某个线程调用yield()方法暂停之后,立即再次获得处理器资源被执行。

    • sleep()方法声明抛出了InterruptedException异常,所以调用sleep()方法时要么捕捉该异常,要么显式声明抛出该异常;而yield()方法则没有声明抛出任何异常。

    • sleep()方法比yield()方法有更好的可移植性,通常不建议使用yield()方法来控制并发线程的执行。

    展开全文
  • Thread 和 启动线程几种方式

    千次阅读 2019-02-15 10:20:09
    启动线程几种方式第一种: 1】d定义Thread类的子类,并重写...3】启动线程,即调用线程的start()方法 注:(start ()是真正的启用了线程 run() 只是thread类的一个方法) 第二种: A类实现runnable 重写run 方...

    1.继承 Thread类(重写 run())

    2.实现 Runnable接口(重写 run())

    3.实现 Callable接口(重写 call())

    启动线程几种方式第一种:
    1、定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体。
    2、创建Thread子类的实例,也就是创建了线程对象
    3、启动线程,即调用线程的start()方法 注:start ()是真正的启用了线程 run() 只是thread类的一个方法
    在这里插入图片描述

    第二种:
    A类实现runnable 重写run 方法
    B类中创建A类的对象
    但是要使用Thread 去把对象当做参数一个启动线程

    方式一:
    在这里插入图片描述
    单独类的写法

    Thread thread = new Thread(){
        @Override
        public void run() {
            System.out.println(123);
         }
    };
    thread.start();
    

    方式二:
    在这里插入图片描述

    第三种:
    实现Callable接口创建线程与Runnable接口的不同之处在于:如果你想要在线程执行完毕之后得到带有返回值的线程则实现Callable接口。
    在这里插入图片描述
    在这里插入图片描述
    特征:
    1.线程有 6 种状态。
    2 每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。 设
    置的优先级不会高于线程组的最大优先级。
    3.每个线程都可以设置成一个守护线程(只能在启动之前设置,不能再启动
    之后设置)。
    4.当新建一个 Thread 时,该线程的初始优先级被设定为创建线程的优先级,
    如果创建线程是守护线程, 那么新线程也是守护线程。
    线程状态:
    NEW: 初始状态,线程被创建, 但是还没有调用 start()。
    RUNNABLE: 运行状态。 Java 线程将操作系统中的就绪和运行两种状态笼统
    地称作“运行中”。
    BLOCKED: 阻塞状态,等待持有锁。
    WAITING:等待状态, 进入该状态表示当前线程需要等待其他线程做出一些
    特定的动作(通知或中断)。
    TIMED_WAITING: 超时等待状态。
    TERMINATED:终止状态。
    方法:
    start():线程启动方法。
    join():堵塞主线程,使其处于等待状态,直到子线程死掉。
    sleep():睡眠指定毫秒, 并不释放 monitor。
    yeild():使当前线程从运行状态变为就绪状态。 cpu 会从众多的可执行态里
    选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并
    不是说一定会执行其他线程而该线程在下一次中不会执行到了。
    suspend(): 将一个线程挂起(暂停), 过时。 它不会释放锁。
    resume(): 将一个挂起线程复活继续执行, 过时。
    interrupt(): 中断线程。 线程的状态被设置为“中断”状态。 线程中断仅仅是设
    置线程的中断状态位,不会停止线程。
    interrupted():清除中断状态,会重置中断状态位为 true。作用于当前线程。
    isInterrupted():静态方法,返回当前线程的中断状态,不会重置中断状态位。
    作用于调用该方法的线程对象所对应的线程。
    holdsLock(obj):判断当前线程是否拥有对象的监视器。
    注意:
    1.wait()方法会释放 CPU 执行权和占有的锁。
    2.sleep(long)方法仅释放 CPU 使用权,锁仍然占用;线程被放入超时等待队
    列,与 yield 相比,它会使线程较长时

    thread jdk 源码
    public class Thread

    implements Runnable {
    private static native void registerNatives();
    static {
    registerNatives();
    }

    private volatile String name;
    private int            priority;
    private Thread         threadQ;
    private long           eetop;
    
    private boolean     single_step;
    
    private boolean     daemon = false;
    
    private boolean     stillborn = false;
    
    private Runnable target;
    
    private ThreadGroup group;
    
    private ClassLoader contextClassLoader;
    
    private AccessControlContext inheritedAccessControlContext;
    
    private static int threadInitNumber;
    private static synchronized int nextThreadNum() {
        return threadInitNumber++;
    }
    
    ThreadLocal.ThreadLocalMap threadLocals = null;
    
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
    
    private long stackSize;
    
    private long nativeParkEventPointer;
    
    private long tid;
    
    private static long threadSeqNumber;
    
    private volatile int threadStatus = 0;
    
    private static synchronized long nextThreadID() {
        return ++threadSeqNumber;
    }
    
    volatile Object parkBlocker;
    
    private volatile Interruptible blocker;
    private final Object blockerLock = new Object();
    
    void blockedOn(Interruptible b) {
        synchronized (blockerLock) {
            blocker = b;
        }
    }
    
    public final static int MIN_PRIORITY = 1;
    
    public final static int NORM_PRIORITY = 5;
    
    public final static int MAX_PRIORITY = 10;
    
    public static native Thread currentThread();
    
    public static native void yield();
    
    public static native void sleep(long millis) throws InterruptedException;
    
    public static void sleep(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
    
        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }
    
        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }
    
        sleep(millis);
    }
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }
    
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
    
        this.name = name;
    
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            if (security != null) {
                g = security.getThreadGroup();
            }
    
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }
    
        g.checkAccess();
    
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }
    
        g.addUnstarted();
    
        this.group = g;
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;
        setPriority(priority);
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        this.stackSize = stackSize;
    
        tid = nextThreadID();
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
    
    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);
    }
    
    public Thread(ThreadGroup group, Runnable target) {
        init(group, target, "Thread-" + nextThreadNum(), 0);
    }
    
    
    public Thread(String name) {
        init(null, null, name, 0);
    }
    
    public Thread(ThreadGroup group, String name) {
        init(group, null, name, 0);
    }
    
    public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }
    
    public Thread(ThreadGroup group, Runnable target, String name) {
        init(group, target, name, 0);
    }
    
    public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
        init(group, target, name, stackSize);
    }
    
    
    public synchronized void start() {
    
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
    
        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        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 */
            }
        }
    }
    
    private native void start0();
    
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
    
    private void exit() {
        if (group != null) {
            group.threadTerminated(this);
            group = null;
        }
        target = null;
        threadLocals = null;
        inheritableThreadLocals = null;
        inheritedAccessControlContext = null;
        blocker = null;
        uncaughtExceptionHandler = null;
    }
    
    @Deprecated
    public final void stop() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            checkAccess();
            if (this != Thread.currentThread()) {
                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        // A zero status value corresponds to "NEW", it can't change to
        // not-NEW because we hold the lock.
        if (threadStatus != 0) {
            resume(); // Wake up thread if it was suspended; no-op otherwise
        }
    
        // The VM can handle all thread states
        stop0(new ThreadDeath());
    }
    
    @Deprecated
    public final synchronized void stop(Throwable obj) {
        throw new UnsupportedOperationException();
    }
    
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();
    
        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }
    
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }
    
    public boolean isInterrupted() {
        return isInterrupted(false);
    }
    private native boolean isInterrupted(boolean ClearInterrupted);
    
    @Deprecated
    public void destroy() {
        throw new NoSuchMethodError();
    }
    
    public final native boolean isAlive();
    
    @Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }
    
    @Deprecated
    public final void resume() {
        checkAccess();
        resume0();
    }
    
    public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess();
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        if((g = getThreadGroup()) != null) {
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            setPriority0(priority = newPriority);
        }
    }
    
    public final int getPriority() {
        return priority;
    }
    public final synchronized void setName(String name) {
        checkAccess();
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
    
        this.name = name;
        if (threadStatus != 0) {
            setNativeName(name);
        }
    }
    public final String getName() {
        return name;
    }
    public final ThreadGroup getThreadGroup() {
        return group;
    }
    
    public static int activeCount() {
        return currentThread().getThreadGroup().activeCount();
    }
    
    public static int enumerate(Thread tarray[]) {
        return currentThread().getThreadGroup().enumerate(tarray);
    }
    @Deprecated
    public native int countStackFrames();
    
    public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;
    
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
    
        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }
    
    public final synchronized void join(long millis, int nanos)
    throws InterruptedException {
    
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
    
        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }
    
        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }
    
        join(millis);
    }
    
    public final void join() throws InterruptedException {
        join(0);
    }
    
    public static void dumpStack() {
        new Exception("Stack trace").printStackTrace();
    }
    public final void setDaemon(boolean on) {
        checkAccess();
        if (isAlive()) {
            throw new IllegalThreadStateException();
        }
        daemon = on;
    }
    
    public final boolean isDaemon() {
        return daemon;
    }
    
    public final void checkAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkAccess(this);
        }
    }
    
    public String toString() {
        ThreadGroup group = getThreadGroup();
        if (group != null) {
            return "Thread[" + getName() + "," + getPriority() + "," +
                           group.getName() + "]";
        } else {
            return "Thread[" + getName() + "," + getPriority() + "," +
                            "" + "]";
        }
    }
    
    @CallerSensitive
    public ClassLoader getContextClassLoader() {
        if (contextClassLoader == null)
            return null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ClassLoader.checkClassLoaderPermission(contextClassLoader,
                                                   Reflection.getCallerClass());
        }
        return contextClassLoader;
    }
    
    public void setContextClassLoader(ClassLoader cl) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
        }
        contextClassLoader = cl;
    }
    
    public static native boolean holdsLock(Object obj);
    
    private static final StackTraceElement[] EMPTY_STACK_TRACE
        = new StackTraceElement[0];
    public StackTraceElement[] getStackTrace() {
        if (this != Thread.currentThread()) {
            // check for getStackTrace permission
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkPermission(
                    SecurityConstants.GET_STACK_TRACE_PERMISSION);
            }
            // optimization so we do not call into the vm for threads that
            // have not yet started or have terminated
            if (!isAlive()) {
                return EMPTY_STACK_TRACE;
            }
            StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
            StackTraceElement[] stackTrace = stackTraceArray[0];
            // a thread that was alive during the previous isAlive call may have
            // since terminated, therefore not having a stacktrace.
            if (stackTrace == null) {
                stackTrace = EMPTY_STACK_TRACE;
            }
            return stackTrace;
        } else {
            // Don't need JVM help for current thread
            return (new Exception()).getStackTrace();
        }
    }
    
    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
        // check for getStackTrace permission
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(
                SecurityConstants.GET_STACK_TRACE_PERMISSION);
            security.checkPermission(
                SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
        }
    
        // Get a snapshot of the list of all threads
        Thread[] threads = getThreads();
        StackTraceElement[][] traces = dumpThreads(threads);
        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
        for (int i = 0; i < threads.length; i++) {
            StackTraceElement[] stackTrace = traces[i];
            if (stackTrace != null) {
                m.put(threads[i], stackTrace);
            }
            // else terminated so we don't put it in the map
        }
        return m;
    }
    
    
    private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
                    new RuntimePermission("enableContextClassLoaderOverride");
    private static class Caches {
        static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
            new ConcurrentHashMap<>();
    
        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
            new ReferenceQueue<>();
    }
    private static boolean isCCLOverridden(Class<?> cl) {
        if (cl == Thread.class)
            return false;
    
        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
        Boolean result = Caches.subclassAudits.get(key);
        if (result == null) {
            result = Boolean.valueOf(auditSubclass(cl));
            Caches.subclassAudits.putIfAbsent(key, result);
        }
    
        return result.booleanValue();
    }
    
    private static boolean auditSubclass(final Class<?> subcl) {
        Boolean result = AccessController.doPrivileged(
            new PrivilegedAction<Boolean>() {
                public Boolean run() {
                    for (Class<?> cl = subcl;
                         cl != Thread.class;
                         cl = cl.getSuperclass())
                    {
                        try {
                            cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
                            return Boolean.TRUE;
                        } catch (NoSuchMethodException ex) {
                        }
                        try {
                            Class<?>[] params = {ClassLoader.class};
                            cl.getDeclaredMethod("setContextClassLoader", params);
                            return Boolean.TRUE;
                        } catch (NoSuchMethodException ex) {
                        }
                    }
                    return Boolean.FALSE;
                }
            }
        );
        return result.booleanValue();
    }
    
    private native static StackTraceElement[][] dumpThreads(Thread[] threads);
    private native static Thread[] getThreads();
    public long getId() {
        return tid;
    }
    
    public enum State {
    public State getState() {
        // get current thread state
        return sun.misc.VM.toThreadState(threadStatus);
    }
    
    // Added in JSR-166
    
    
    @FunctionalInterface
    public interface UncaughtExceptionHandler {
        /**
         * Method invoked when the given thread terminates due to the
         * given uncaught exception.
         * <p>Any exception thrown by this method will be ignored by the
         * Java Virtual Machine.
         * @param t the thread
         * @param e the exception
         */
        void uncaughtException(Thread t, Throwable e);
    }
    
    // null unless explicitly set
    private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
    
    // null unless explicitly set
    private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
    
    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(
                new RuntimePermission("setDefaultUncaughtExceptionHandler")
                    );
        }
    
         defaultUncaughtExceptionHandler = eh;
     }
    
    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
        return defaultUncaughtExceptionHandler;
    }
    
    public UncaughtExceptionHandler getUncaughtExceptionHandler() {
        return uncaughtExceptionHandler != null ?
            uncaughtExceptionHandler : group;
    }
    
    public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        checkAccess();
        uncaughtExceptionHandler = eh;
    }
    
    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }
    
    static void processQueue(ReferenceQueue<Class<?>> queue,
                             ConcurrentMap<? extends
                             WeakReference<Class<?>>, ?> map)
    {
        Reference<? extends Class<?>> ref;
        while((ref = queue.poll()) != null) {
            map.remove(ref);
        }
    }
    
    static class WeakClassKey extends WeakReference<Class<?>> {
        private final int hash;
    
        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
            super(cl, refQueue);
            hash = System.identityHashCode(cl);
        }
    
        @Override
        public int hashCode() {
            return hash;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;
    
            if (obj instanceof WeakClassKey) {
                Object referent = get();
                return (referent != null) &&
                       (referent == ((WeakClassKey) obj).get());
            } else {
                return false;
            }
        }
    }
    
    
    /** The current seed for a ThreadLocalRandom */
    @sun.misc.Contended("tlr")
    long threadLocalRandomSeed;
    
    /** Probe hash value; nonzero if threadLocalRandomSeed initialized */
    @sun.misc.Contended("tlr")
    int threadLocalRandomProbe;
    
    /** Secondary seed isolated from public ThreadLocalRandom sequence */
    @sun.misc.Contended("tlr")
    int threadLocalRandomSecondarySeed;
    
    private native void setPriority0(int newPriority);
    private native void stop0(Object o);
    private native void suspend0();
    private native void resume0();
    private native void interrupt0();
    private native void setNativeName(String name);
    

    }

    展开全文
  • 创建和启动线程的两种方式

    万次阅读 多人点赞 2016-10-07 10:52:48
    方式1:继承Thread类 步骤: 1):定义一个类A继承于java.lang.Thread类. 2):在A类中覆盖Thread类中的run方法. ...4):在main方法(线程)中,创建线程对象,并启动线程. (1)创建线程类对象: A类 a = new A类();

    方式1:继承Thread

    步骤:

    1):定义一个类A继承于java.lang.Thread.

    2):A类中覆盖Thread类中的run方法.

    3):我们在run方法中编写需要执行的操作:run方法里的代码,线程执行体.

    4):main方法(线程),创建线程对象,并启动线程.

    (1)创建线程类对象:                

    A类   a  =  new   A();

    (2)调用线程对象的start方法:    

    a.start();//启动一个线程

     

    注意:千万不要调用run方法,如果调用run方法好比是对象调用方法,依然还是只有一个线程,并没有开启新的线程.

    线程只能启动一次!

    创建启动线程实例:

    //1):定义一个类A继承于java.lang.Thread类.
    class MusicThread extends Thread{
    	//2):在A类中覆盖Thread类中的run方法.
    	public void run() {
    		//3):在run方法中编写需要执行的操作
    		for(int i = 0; i < 50; i ++){
    			System.out.println("播放音乐"+i);
    		}
    	}
    }
    
    public class ExtendsThreadDemo {
    	public static void main(String[] args) {
    		
    		for(int j = 0; j < 50; j ++){
    			System.out.println("运行游戏"+j);
    			if(j == 10){
    				//4):在main方法(线程)中,创建线程对象,并启动线程.
    				MusicThread music = new MusicThread();
    				music.start();
    			}
    		}
    	}
    
    }


    方式2:实现Runnable接口

    步骤:

    1):定义一个类A实现于java.lang.Runnable接口,注意A类不是线程类.

    2):A类中覆盖Runnable接口中的run方法.

    3):我们在run方法中编写需要执行的操作:run方法里的,线程执行体.

    4):main方法(线程),创建线程对象,并启动线程.

         (1)创建线程类对象:

         Thread  t = new Thread(new  A());    

         (2)调用线程对象的start方法:

         t.start();

     

    //1):定义一个类A实现于java.lang.Runnable接口,注意A类不是线程类.
    class MusicImplements implements Runnable{
    	//2):在A类中覆盖Runnable接口中的run方法.
    	public void run() {
    		//3):在run方法中编写需要执行的操作
    		for(int i = 0; i < 50; i ++){
    			System.out.println("播放音乐"+i);
    		}
    		
    	}
    }
    
    public class ImplementsRunnableDemo {
    	public static void main(String[] args) {
    		for(int j = 0; j < 50; j ++){
    			System.out.println("运行游戏"+j);
    			if(j == 10){
    			    //4):在main方法(线程)中,创建线程对象,并启动线程
    				MusicImplements mi = new MusicImplements();
    				Thread t = new Thread(mi);
    				t.start();
    			}
    		}
    	}
    
    }

    分析继承方式和实现方式的区别:

    继承方式:
                    1):从设计上分析,Java中类是单继承的,如果继承了Thread了,该类就不能再有其他的直接父类了.
                    2):从操作上分析,继承方式更简单,获取线程名字也简单.(操作上,更简单)
                    3):从多线程共享同一个资源上分析,继承方式不能做到.
    实现方式:
                    1):从设计上分析,Java中类可以多实现接口,此时该类还可以继承其他类,并且还可以实现其他接口,设计更为合理.
                    2):从操作上分析,实现方式稍微复杂点,获取线程名字也比较复杂,得使用Thread.currentThread()来获取当前线程的引用.

                   3):从多线程共享同一个资源上分析,实现方式可以做到(是否共享同一个资源).


    补充:实现方式获取线程名字:

    String name = Thread.currentThread().getName();




    展开全文
  • java多线程之启动线程的三种方式

    万次阅读 多人点赞 2018-08-12 14:42:08
    java对多线程有着良好的支持,java创建和启动线程较为常用的方式有继承Thread类、实现Runnable接口和匿名内部类的方式。 1.继承Thread类: 通过继承Thread类来创建并启动多线程步骤如下: 1、定义Thread类的子类...
  • java实现多线程有两种方法 1、继承Thread类,实现run方法 2、
  • 方式一:继承Thread类;步骤:1)定义一个类 A继承于java.lang.Thread类;2)在A类中覆盖Thread...4)在main方法(线程)中,创建线程对象,并启动线程。创建线程类对象: A类 a = new A类( );调用线程对象的start...
  • Java启动线程两种方式总结

    千次阅读 2018-07-12 14:40:48
    先查看jdk帮助文档,这么进行描述线程线程是程序中的执行线程,可以由jvm来运行一个或者多个线程方法1:继承Thread 类 重写run方法即可 如下代码: public class Treadtest { //主方法 public static...
  • 线程相关方法详解

    万次阅读 2018-04-18 11:01:29
      用start() 方法启动线程,真正实现了多线程运行,这时无需等待run() 方法内代码执行完毕,而是直接继续执行下面的代码。通过start()方法启动一个线程后,线程处于就绪状态,并没有运行,一旦得到CPU时间片,就...
  • 原题目是启动线程的三种方式,我理解为java中启动线程的三种方式,在这里又补充了一些Android中启动线程的方式 Java中启动线程的三种方式 三种方式 1. 继承Thread类创建线程类,通过start方法开启新线程 使用方式...
  • 线程(一):创建线程线程的常用方法

    万次阅读 多人点赞 2018-09-01 19:14:23
    一:为什么要学多线程 应付面试 :多线程几乎是面试中必问的题,所以掌握一定的基础知识是必须的。 了解并发编程:实际工作中很少写多线程的代码,这部分代码一般都被人封装起来了,在业务中使用多线程的机会也...
  • 使用Callable与Future来创建启动线程

    千次阅读 2016-03-04 21:45:48
    使用Callable与Future来创建启动线程  1.创建Callable的实现类,并冲写call()方法,该方法为线程执行,并且该方法有返回值  2.创建Callable的实例,并用FutuerTask类来包装Callable对象,该FutuerTask...
  • 首先请看一下如下的代码:设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。public class ThreadTest1{ private int j;...
  • run方法运行结果 run()方法只是类的一个普通方法,如果直接调用run()方法...用start方法启动线程,真正实现了多线程运行,这时无需等待run方法体中的代码执行完毕而直接继续执行后续的代码。通过调用Thread类的...
  • java开启新线程的三种方法方法1:继承Thread类 ...4):在main方法(线程)中,创建一个线程对象并启动线程。 (1)创建线程类对象: A类 a = new A类(); (2)调用线程对象的start方法: a.start();...
  • 1.start()方法:用来启动线程,实现了多线程的运行,通过调用Tread类的start方法来启动一个线程,这时此线程处于就绪态,没有运行,当此条线程得到了cpu的时间片,就开始执行run方法,这里的run方法称为线程体,他...
  • 方式2:通过实现Runnable接口步骤: 1.定义一个类A实现于java.lang.Runnable接口。(注意A类不是线程类) ...4.在main方法(线程)中,创建线程并启动线程// 播放音乐的类 class MusicR implements java.lang.Runnable{
  • 启动线程的三种方式

    千次阅读 2018-06-21 09:35:47
    注意:启动线程的方式有且只有调用start方法 4.比较: 实现Runnable接口优势: 1)适合多个相同的程序代码的线程去处理同一个资源 2)可以避免java中的单继承的限制 3)增加程序的健壮性,代码可以被多个线程共享,...
  • 因为thread线程有5种状态,创建-就绪-运行-阻塞-死亡这五种,用Thread类的start()方法启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,等到cpu空闲时,才会执行线程里面的run方法,run方法运行完毕...
  • java之内部类中启动线程

    千次阅读 2017-12-22 09:28:29
    2 如果想要在内部类中启动线程。并调用它。则和在方法体中启动一个线程差不多。不过该方法是内部类中的方法。传递的参数为list类型最好。 如:public class TestNeibuleiThread { public void test(){ ...
  • 1、用 start()方法启动线程,真正实现了多线程运行。它无需等 run()方法执行完毕就可以执行下面的代码。(因为此时线程正处于排队的空闲,可以做别的事) 通过调用 Thread类 的 start()方法,线程进入就绪(可...
  • 线程启动方式

    2017-04-01 16:50:06
    继承Thread类,实现run()方法,调用Thread的start()方法启动线程,线程的执行就是run()方法中的代码块。2、Runnable接口创建线程: 定义Runnable接口的实现类,并重写接口的run()方法,创建该类的实例,将该...
  • java多线程run方法传参

    万次阅读 2018-09-25 20:32:40
    我们知道多线程是通过star()方法线程处于准备就绪状态,而实际运行的业务逻辑是放在run()方法体中的,但是run()方法是没有参数的方法,实际的业务场景中,我们可能需要向方法体中传递参数,下面介绍常用的两种传参...
  • 定义线程方法Thread

    2018-09-30 16:23:21
    main:  public class Test { public static void main(String[] args) { while(true){ //创建线程对象 Thread thread=new TortoiseThread(); //启动线程 ...
  •  start()方法启动线程后,整个线程处于就绪状态,等待虚拟机调度, 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此...
  • 实现并启动线程有两种方法 1、写一个类继承自Thread类,重写run方法。用start方法启动线程 2、写一个类实现Runnable接口,实现run方法。用new Thread(Runnable target).start()方法来启动多线程原理:相当于玩游戏机...
  • Java多线程 - 线程创建和启动

    千次阅读 2018-06-06 23:26:27
    线程的创建一般有以下三种:一、继承Thread类创建线程类定义Thread类的子类,并重写该类的run()方法,该run()方法方法体就代表了线程需要完成的任务,因此经常把run()方法称为线程执行。创建Thread子类的...
  • Java线程的相关方法串联线程知识

    千次阅读 2013-09-03 00:06:45
    ~ start() 启动线程方法 ~ run() 调用start()方法时,真正执行的就是该方法方法体 ~ sleep() 让当前线程睡眠,睡眠到期自动苏醒,并进入可运行状态,而不是运行状态 ~ yield() 暂停当前正在执行的线程对象,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 102,142
精华内容 40,856
关键字:

启动线程体的方法