一个、正在创建的线程:
老掉牙的话题了。继承 java.lang.Thread父类或者实现Runnalbe接口。这里就提一句:
class Thread implements RunnableThread也是继承了Runnable接口的,Runnable才是大哥。
重写run(),run()里放的都是详细的业务,包含对线程的详细操作。
class Thread1 implements Runnable { int i; Thread1(int i) { this.i = i; } @Override public void run() { long x = new Random().nextInt(10)*1000; try { Thread.sleep(x); } catch (InterruptedException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } System.out.println("线程"+ i + "睡眠" + x); } }二、线程的调用:
独立的线程启动方式—Thread的start()方式,
class Thread1Execute { public static void main(String[] args) { // 创建线程 Thread thread = new Thread(new Thread1(99)); // 启动命令 thread.start(); } }线程池启动 ExecutorService
public class SleepTest1 { public static void main(String[] args) { // 创建线程池,这里用了向上造型。事实上newCachedThreadPool出来的类是ThreadPoolExecutor。 ExecutorService executor = Executors.newCachedThreadPool(); for (int i=0;i<10 ; i++) { // 运行10个线程 executor.execute(new Thread1(i)); } //关闭线程池 executor.shutdown(); } }
三、线程优先级:
线程里设置优先级。JDK里有10个优先级,但JDK得优先级与操作系统兼容的并不好,因此,在编程的时候。仅仅是用三个优先级
/** * The minimum priority that a thread can have. */ public final static int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public final static int MAX_PRIORITY = 10;</span>
设置优先级的代码要放到run()的开头部分。
public void run() { // 设置优先级为最高。 Thread.currentThread().setPriority(Thread.MAX_PRIORITY); }
四、让步Thread.yield()
yield()方法仅仅只是是一个暗示,不能保证它被採用。因此。在对重要的线程进行控制的时候,慎用。
五、后台线程
后台线程也叫守护线程,顾名思义就是在后台跑的线程,不会因正常线程的结束而结束。
设置方法为,在线程启动之前,thread.setDaemon(true);
由于Thread默认的daemon是false,參照代码例如以下:
/* Whether or not the thread is a daemon thread. */ private boolean daemon = false;代码演示样例:
class Thread1Execute { public static void main(String[] args) throws InterruptedException { for (int i=0;i<10 ; i++) { // 创建线程 Thread thread = new Thread(new Thread1(i)); thread.setDaemon(true); // 启动命令 thread.start(); } System.out.println("main睡眠"); Thread.sleep(10000); System.out.println("main醒来"); } }输出结果为:
main睡眠 线程6睡眠2000 线程8睡眠2000 线程3睡眠3000 线程7睡眠4000 线程1睡眠5000 线程0睡眠5000 线程9睡眠5000 线程5睡眠7000 线程4睡眠8000 线程2睡眠8000 main醒来
能够看出,后台进程不受Main线程的控制。在main睡眠期间,他们依旧辛劳耕种。
但当最后一个非后台线程退出时,后台线程会“突然”终止,也就是说一旦main()退出。JVM将关闭全部后台线程。
因此,这样的后台线程并不好控制。不推荐在实际项目中使用。
另一种线程池的创建后台进程的方式。这样的方式略微有那么一点点复杂
Executors.newCachedThreadPool(new DaemonThreadFactory());这里须要传入一个线程工厂。
public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(new DaemonThreadFactory()); for(int i = 0; i < 10; i++) exec.execute(new DaemonFromFactory()); System.out.println("All daemons started"); TimeUnit.MILLISECONDS.sleep(500); // Run for a while }工厂的定义例如以下,作用为将全部创建出来的线程都设置为Daemon后台线程类型。
class DaemonThreadFactory implements ThreadFactory { @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setDaemon(true); return t; } }
这样的灵感来源于java.util.concurrent.Executors的默认线程工厂。
/** * The default thread factory */ static class DefaultThreadFactory implements ThreadFactory { static final AtomicInteger poolNumber = new AtomicInteger(1); final ThreadGroup group; final AtomicInteger threadNumber = new AtomicInteger(1); final String namePrefix; DefaultThreadFactory() { SecurityManager s = System.getSecurityManager(); group = (s != null)? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; } public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); if (t.isDaemon()) t.setDaemon(false); if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); return t; } }
先讲这么多,线程这块的东西实在是太多了,理解起来也很难。
有那么一本书推荐一下《JAVA并发编程实践》这本书是专门讲并发的,我打算下个月就開始写那本书的阅读日记,当然还有传说中的《Head first设计模式》。
版权声明:本文博客原创文章,博客,未经同意,不得转载。