1、Runable
Runable 是线程家族的顶级父类,只提供了run 方法
2、Thread
Thread 是Runable的实现类之一,也是我们经常用到的线程类,下面来列举这个类的几个常用方法
2.1 构造器
public Thread(Runnable target) //工作线程构造器
public Thread(ThreadGroup group, Runnable target) //线程组方式构造器,用来管理一组现场
比如
ThreadGroup threadGroup = new ThreadGroup("线程组"); Thread thread = new Thread(threadGroup,new ThreadTest()); thread.start(); threadGroup.activeCount();
2.2 方法
yield 、sleep 、suspend和resume 、wait和notify和notityAll
yield:如果用了这个方法,当前线程可能让出cpu调度权(这个可能的意思是指,yield只是个cpu一个提示说让出当前工作线程的调度,cpu可能会立即执行,也可能稍后执行,yield不阻塞)
public class ThreadTest extends Thread { private static AtomicInteger count = new AtomicInteger(0); private static final CountDownLatch start = new CountDownLatch(1); private static final CountDownLatch end = new CountDownLatch(10); @Override public void run() { try { start.await(); this.task(); } catch (InterruptedException e) { e.printStackTrace(); }finally { end.countDown(); } } private void task(){ count.addAndGet(1); if(count.compareAndSet(2,2)){ Thread.yield(); System.out.println("让出线程调度"); } System.out.println(count.get()); } public static void main(String[] args) throws InterruptedException { ThreadGroup group = new ThreadGroup("线程组"); for(int i=0;i<10;i++){ Thread thread = new Thread(group,new ThreadTest()); thread.start(); } start.countDown(); end.await(); Thread.sleep(2000); } }
1
让出线程调度
4
4
6
3
7
5
8
9
10
上面的结果可以看出,yield让出cpu调度后会自动恢复(这个回复的时间又cpu决定)
sleep:sleep是一个阻塞的方法,暂停当前工作线程(其他线程也不可以获取cpu的调度)
Thread.sleep(2000); 阻塞 2s
suspend和resume 这两个方法是当线程到达某个状态时,如果是用suspend方法时,线程阻塞,当状态改变的时候调用resume,线程恢复执行(这个两个方法很少用到,也应该尽量不用,这两个方法也是废弃)
wait和notify 是suspend和resume的替代品(当然不能说是替代品,因为他们之间存在区别,主要的区别是wait不是阻塞的,notify 是唤醒wait线程的方法)
public class ThreadTest extends Thread { private static int count = 0; private static final CountDownLatch start = new CountDownLatch(1); private static final CountDownLatch end = new CountDownLatch(10); private static final Object obj = new Object(); @Override public void run() { try { start.await(); this.task(); } catch (InterruptedException e) { e.printStackTrace(); }finally { end.countDown(); } } private void task() throws InterruptedException { synchronized (obj){ count++; if(count == 2){ obj.wait(); System.out.println("让出线程调度"); }else if (count == 3){ obj.notifyAll(); } System.out.println(count); } } public static void main(String[] args) throws InterruptedException { ThreadGroup group = new ThreadGroup("线程组"); for(int i=0;i<10;i++){ Thread thread = new Thread(group,new ThreadTest()); thread.start(); } start.countDown(); end.await(); Thread.sleep(2000); } }
1
3
4
5
让出线程调度
5
6
7
8
9
10
可以看出,notify()和notifyAll() 会唤醒wait线程
2.3 join方法,是合并两个线程(其实还是在单线程的工程模式,其实觉得这种方式没用)
join()
Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("子线程工作..."); } }); thread.start(); thread.join(); //直到子线程工作完成工作 System.out.println("主线程的后续工作...");
3、ThreadGroup
线程组管理一组线程,可以查看当前线程组活动的现场数量,添加线程,移除线程等操作