多线程一(线程的创建、优先级、睡眠、守护、让步、合并)

1.创建线程的三种方式:

  • 继承Thread类,重写run方法
  • 实现Runnable接口,重写run方法
  • 如果有返回值,要实现Callable接口(带泛型),重写call方法。再通过Callable的实现类构建FutureTask类,再通过FutureTask类来构建Thread类。
    第一种:
public class Demo01 extends Thread {
    @Override public void run() {
       for(int i=0;i<100;i++)
       {
           System.out.println(Thread.currentThread().getName()+"\ti-------"+i);
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
    }
    public static void main(String[] args) {
        Thread thread1=new Thread(new Demo01(),"count");
        thread1.start();
    }
}

第二种(通过匿名内部类来实现):

public class Demo01 extends Thread {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override public void run() {
                for(int i=0;i<100;i++)
                {
                    System.out.println(Thread.currentThread().getName()+"\ti-------"+i);
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"count").start();
    }
}

以上两个线程都是从1数到100的线程。第一个继承了Thread类,因此不能再继承其他类。第二个是通过匿名内部类来实现Runnable接口,还可以继承其他的类,因此第二种较为常用。
第三种(带返回值):

public class Demo01 extends Thread {
    static class thread implements Callable<Integer>
    {
        @Override public Integer call() throws Exception {
            int sum=0;
            for(int i=0;i<101;i++)
            {
                sum+=i;
            }
            return new Integer(sum);
        }
    }
    public static void main(String[] args) throws Exception {
        FutureTask futureTask=new FutureTask(new thread());
        Thread thread1=new Thread(futureTask,"add");
        thread1.start();
        System.out.println("求和:"+futureTask.get());
    }
}

也可以通过匿名内部类来实现。
2.线程的优先级:总共有10个优先级,优先级越高会越先执行。count类是一个实现了Runnable的类,功能是计数。

 public static void main(String[] args) {
        Thread thread1=new Thread(new count(),"thread1");
        Thread thread2=new Thread(new count(),"thread2");
        thread1.setPriority(1);
        thread2.setPriority(10);
        thread1.start();
        thread2.start();
    }

当两个线程的优先级差距很大时,总是优先级高的先执行完,然后才执行优先级低的。将线程2的优先级降低后,在线程2未执行完的时候线程1也执行了。这也就意味着两个线程运行时,优先级较高的抢占到CPU的概率越高。
2.线程睡眠:

 for(int i=0;i<100;i++)
        {
            System.out.println(Thread.currentThread().getName()+"\t\t"+i);
            Thread.sleep(500);
        }

效果为每隔0.5秒输出一次。
3.设置守护线程,当别的线程执行完后,无论守护线程是否执行完都要结束。即使是内部的循环也不能执行完。

public class Demo01 {
    public static void main(String[] args){
        Thread thread1=new Thread(new Runnable() {
            @Override public void run() {
                int i=0;
                while(true)
                {
                    System.out.println("守护线程:"+i++);
                }
            }
        });
        thread1.setDaemon(true);
        Thread thread2=new Thread(new Runnable() {
            @Override public void run() {
                for(int i=0;i<100;i++)
                {
                    System.out.println("普通线程:"+i);
                }
            }
        });
        thread1.start();
        thread2.start();
    }
}

运行结果:在普通线程结束后,守护线程计数到117也结束。如果将thread1.setDaemon(true); 这一行注释掉,守护线程会一直向下数。
4.线程的让步:通过静态方法Thread.yield() ,让出CPU,但还是会去抢,同样也有可能抢到。
5.线程合并:调用Thread中的实例方法join()。调用该方法的线程会先执行完,之后再执行其他线程。

public class Demo01 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread1=new Thread(new Runnable() {
            @Override public void run() {
               for(int i=0;i<1001;i++)
               {
                   System.out.println(Thread.currentThread().getName()+"---------"+i);
               }
            }
        },"thread1");
        Thread thread2=new Thread(new Runnable() {
            @Override public void run() {
                for(int i=0;i<1001;i++)
                {
                    System.out.println(Thread.currentThread().getName()+"---------"+i);
                    try {
                        if(i==500)thread1.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"thread2");
        thread1.start();
        thread2.start();
    }
}

两个计数的线程,第二个线程数到500时,将第一个线程合并进来,然后执行线程1,直到线程1执行完后再执行线程2。
运行结果(部分):

thread2---------499
thread2---------500
thread1---------113
thread1---------114
......
thread1---------998
thread1---------999
thread1---------1000
thread2---------501
thread2---------502

猜你喜欢

转载自blog.csdn.net/Hello_1024/article/details/83545649
今日推荐