本文共 22629 字,大约阅读时间需要 75 分钟。
进程:(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在进程是程序的基本执行实体,在当代面向线程设计的计算机结构中,进程是线程的容器,程是程序的实体。
多线程:是指从软件或者硬件上实现多个线程并发执行的技术,是为了提高CPU等资源的使用率而采用的一种新技术。将一个执行活动-进程,拆分为多个小的执行片段,片段之间是共享数据而完成进程任务,进而提升整体处理性能。
Java程序运行
进程的实现方式:
继承Thread类.
/*for example*/public final String getName() //获取线程的名称。public final void setName(String //name):设置线程的名称System.out.println(Thread.currentThread().getName()); //控制台显示当前指定对象名字。public class MyThread extends Thread { public MyThread() { } public MyThread(String name){ super(name); } @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); } }}public static void main(String[] args) { /*method:the first...*/ MyThread myThread1 = new MyThread(); MyThread myThread2 = new MyThread(); myThread1.setName("Tom"); myThread2.setName("Jack"); myThread1.start(); myThread2.start(); /*method:the second...*/ MyThread Thread1 = new MyThread("Tom"); MyThread Thread2 = new MyThread("Jack"); Thread1.start(); Thread2.start();
实现Runnable接口.
public class MyRunnable implements Runnable { @Override public void run() { for (int x = 0; x < 10; x++) { System.out.println(Thread.currentThread().getName() + ":" + x); } }}public class MyRunnable { public static void main(String[] args) { MyRunnable my = new MyRunnable(); /*method:the first...*/ Thread Thread1 = new Thread(my); Thread Thread2 = new Thread(my); Thread1.setName("Tom"); Thread2.setName("Jack"); /*method:the second...*/ Thread Thread1 = new Thread(my, "Tom"); Thread Thread2 = new Thread(my, "Jack"); Thread1.start(); Thread2.start(); }}
Callable&ExecutorService.
/*for example*/ import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; import java.util.concurrent.Callable;/*Callable:是带泛型的接口,这里指定的泛型其实是call()方法的返回值类型*/@SuppressWarnings("rawtypes")class MyCallable implements Callable { /*Callable JDK1.5*/ @Override public Object call() throws Exception { for (int x = 0; x < 50; x++) { System.out.println(Thread.currentThread().getName() + ":" + x); } return null; }}public class CallableDemo { public static void main(String[] args) { /*创建线程池对象*/ ExecutorService pool = Executors.newFixedThreadPool(2); pool.submit(new MyCallable()); pool.submit(new MyCallable()); pool.shutdown(); }}
线程的调度和优先级问题
线程的控制
休眠线程
/*for example*//* public static void sleep(long millis) */import java.util.Date;public class ThreadSleep extends Thread { @Override public void run() { for (int x = 0; x < 20; x++) { System.out.println(getName() + ":" + x + ",Date:" + new Date()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } /* 解决直接重命名线程名称.*/ /*public ThreadSleep(String name){ super(name); }*/}public class ThreadSleepDemo { public static void main(String[] args) { ThreadSleep Aa = new ThreadSleep(); ThreadSleep Bb = new ThreadSleep(); ThreadSleep Cc = new ThreadSleep(); /*ThreadSleep Dd = new ThreadSleep("Smith");*/ Aa.setName("Tom"); Bb.setName("John"); Cc.setName("Jack"); Aa.start(); Bb.start(); Cc.start(); }}
加入线程
/*实现join功能*/package CompareTools;class sleepThread extends Thread { @Override public void run() { for (int i = 0; i < 10; ++i) { try { sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + ":" + i); } } public sleepThread() { } public sleepThread(String name) { super(name); }}public class TestFiles { public static void main(String[] args) { // TODO Auto-generated method stub sleepThread spOne = new sleepThread("Tom"); sleepThread spTwo = new sleepThread("Jack"); sleepThread spThree = new sleepThread("Smith"); spThree.start(); try { spThree.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } spOne.start(); spTwo.start(); }}/*Smith执行完成才继续执行后面的,但若将spThree放到try后面不会有描述的效果。*/
礼让线程
package CompareTools;class PriorityThread implements Runnable { @Override public void run() { for (int i = 0; i < 10; ++i) { /* 实现Runnable无法使用Thread的getName函数. */ System.out.println(Thread.currentThread().getName() + ":" + i); Thread.yield(); /*礼让不代表一定是程序严格运行一次就对方执行.*/ } }}public class TestFiles { public static void main(String[] args) { PriorityThread pt = new PriorityThread(); PriorityThread ptt = new PriorityThread(); Thread trr = new Thread(pt, "Jack"); /*Thread trr = new Thread(pt, "Tom")一样运行看不出什么问题.*/ Thread tr = new Thread(ptt, "Tom"); tr.setName("newName"); trr.setName("newNameName"); tr.start(); trr.start(); }}
守护线程
/*public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。*/ 当正在运行的线程都是守护线程时,Java 虚拟机退出。/*for example*/td1.setDaemon(true);td2.setDaemon(true);td1.start();td2.start();System.out.println("Over!");result:--循环结构写稍微大一些可以看到效果,循环到部分虚拟机就退出。Over!Thread-1:0Thread-0:0Thread-1:1Thread-0:1Thread-1:2Thread-0:2Thread-1:3Thread-1:4Thread-1:5Thread-1:6Thread-0:3Thread-1:7Thread-1:8Thread-0:4Thread-1:9Thread-1:10...
优先级设置
package CompareTools;/*设置优先级不能保证一定是是优先级高的限制性,java中只能表示优先,但是不是先执行完高级别的再执行低级别.*/class PriorityThread implements Runnable { @Override public void run() { for (int i = 0; i < 10; ++i) { System.out.println(Thread.currentThread().getName() + ":" + i); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }}public class TestFiles { public static void main(String[] args) { PriorityThread pt = new PriorityThread(); Thread tr = new Thread(pt, "Jack"); Thread trr = new Thread(pt, "Tom"); Thread trrr = new Thread(pt, "Smith"); tr.setPriority(10); trrr.setPriority(1); tr.start(); trr.start(); trrr.start(); }}
终止线程
import java.util.Date;public class ThreadStop extends Thread { @Override public void run() { System.out.println("开始执行:" + new Date()); /*睡眠10s*/ try { Thread.sleep(10000); } catch (InterruptedException e) { System.out.println("线程被终止了!"); } System.out.println("结束执行:" + new Date()); }}public class ThreadStopDemo { public static void main(String[] args) { ThreadStop ts = new ThreadStop(); ts.start(); /*3s不继续执行,中断.*/ try { Thread.sleep(3000); /*ts.stop(); 直接终止.*/ ts.interrupt(); //线程被终止,结束执行还是可以显示. } catch (InterruptedException e) { e.printStackTrace(); } }}
加入并查看线程组
public class ThreadGroupDemo { public static void main(String[] args){ methodOne(); methodTwo(); } private static void methodTwo() { ThreadGroup SetGroup = new ThreadGroup("NewGroupName"); MyRunnable SetThreadRunable = new MyRunnable(); Thread t1 = new Thread(SetGroup, SetThreadRunable, "TheOne"); Thread t2 = new Thread(SetGroup, SetThreadRunable, "TheTwo"); System.out.println(t1.getThreadGroup().getName()); System.out.println(t2.getThreadGroup().getName()); SetGroup.setDaemon(true); } private static void methodOne() { MyRunnable SourceRunable = new MyRunnable(); Thread t1 = new Thread(SourceRunable, "FirstThread"); Thread t2 = new Thread(SourceRunable, "SecondThread"); /*查看默认情况下,线程所属组别--默认是Main.*/ ThreadGroup defaultTg1 = t1.getThreadGroup(); ThreadGroup defaultTg2 = t2.getThreadGroup(); String nameOne = defaultTg1.getName(); String nameTwo = defaultTg2.getName(); System.out.println(nameOne); System.out.println(nameTwo); System.out.println(Thread.currentThread().getThreadGroup().getName()); }}
线程的生命周期
新建->就绪->运行->阻塞->死亡。车站买票完整实现
描述:买票用多线程实现,可以考虑适当的延迟,或者是为了保证程序的健壮性,保证问题不被掩盖掉。问题有这两种:一个是同一张车票卖了两次,二是车票卖到了负数。
如图出错:
为了数据的安全性需要添加锁进行实现而锁有两种:一种是Synchronized实现,一种是JDK1.4之后的lock实现。
/*for example*//*method:the first... */class SellTicket implements Runnable { private static int tickets = 100; private Object obj = new Object(); @Override public void run() { while (true) { /*在需要锁的地方添加锁对象,或者用obj替换SellTicket.class亦可!*/ /*this=SellTicket.class*/ synchronized (SellTicket.class) { if (tickets > 0) { try { Thread.sleep(150); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "printing" + (tickets--) + "th ticke!");}}}}}public class SellTicketDemo { public static void main(String[] args) { // 创建资源对象. SellTicket st = new SellTicket(); Thread thead1 = new Thread(st, "Windows-1:"); Thread thead2 = new Thread(st, "Windows-2:"); Thread thead3 = new Thread(st, "Windows-3:"); thead1.start(); thead2.start(); thead3.start(); }}/*method:the second... */package CompareTools;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class SellTicket implements Runnable { private static int tickets = 100; private Lock lock = new ReentrantLock(); @Override public void run() { while (true) { try { lock.lock(); if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "Printing" + (tickets--) + "th tickes!"); } } finally { lock.unlock(); } } }}public class TestFiles { public static void main(String[] args) { SellTicket sourceClass = new SellTicket(); Thread sta = new Thread(sourceClass, "Windows-1:"); Thread stb = new Thread(sourceClass, "Windows-2:"); Thread stc = new Thread(sourceClass, "Windows-3:"); sta.start(); stb.start(); stc.start(); } }
未曾达到预期结果,出错代码在runable下运行正常,原因可能是实现接口的子类存在于Thread子类特有的差别,目前还无法明白具体原因,出错实例如下:
/*for example--出错.*/--lock锁搭配try...finally...出错。package CompareTools;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class SellTicket extends Thread { private static int tickets = 100; private Lock lock = new ReentrantLock(); public SellTicket() { } public SellTicket(String name) { super(name); } @Override public void run() { while (true) { try{ lock.lock(); if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + "Printing" + (tickets--) + "th tickes!"); } }finally{ lock.unlock();} } } }public class TestFiles { public static void main(String[] args) { SellTicket sta = new SellTicket("Windows-1:"); SellTicket stb = new SellTicket("Windows-2:"); SellTicket stc = new SellTicket("Windows-3:"); sta.start(); stb.start(); stc.start(); }}
多线程安全判定
同步方法
class SellTicket implements Runnable { private static int tickets = 100; private int x = 0; @Override public void run() { while (true) { if (x % 2 == 0) { synchronized (SellTicket.class) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "printing" + (tickets--) + "th ticket! "); } } } else { sellTicket(); } x++; } } private static synchronized void sellTicket() { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "printing" + (tickets--) + "th ticket! "); } }}public class SellTicketDemo { public static void main(String[] args) { SellTicket sourceClass = new SellTicket(); Thread window_1 = new Thread(sourceClass, "window_1:\t"); Thread window_2 = new Thread(sourceClass, "window_2:\t"); Thread window_3 = new Thread(sourceClass, "window_3:\t"); window_1.start(); window_2.start(); window_3.start(); }}
同步的使用可以修改为对:要求线程严格遵守一个线程执行一次的要求,也可以利用经典的互斥问题,哲学家就餐问题和生产消费问题。
描述:问题的起源。
首先是由于线程的不严格控制导致的生产消费的死锁问题,也就是多个对象占有其他对象所必需的资源,导致自己无法获取资源,陷入无限等待的姿态。
互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
解除死锁状态
死锁预防:这是一种较简单和直观的事先预防的方法。方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。
死锁避免:系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源;如果分配后系统可能发生死锁,则不予分配,否则予以分配。这是一种保证系统不进入死锁状态的动态策略。
死锁检测和解除:先检测,这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源。检测方法包括定时检测、效率低时检测、进程等待时检测等。
Code 同步互斥:
/*Object类中提供的三个方法: wait():等待 notify():唤醒单个线程 notifyAll():唤醒所有线程 为什么不定义在Thread类中? 这些方法的调用必须通过锁对象Lock调用,而我们使用的锁对象可能是任意锁对象. 所以,这些方法必须定义在Object类中是为了实现对象的通用性。*//* Tom-5. * Jack-6. *//*该部分代码块实现的是:多线程情况下,保证线程运行一步就暂停,而然另外线程运行*/package CompareTools;class Student { String name; int age; boolean flag;}class GetThread implements Runnable { private Student s; public GetThread(Student s) { this.s = s; } @Override public void run() { while (true) { synchronized (s) { /*锁定局部,而实际造成的结果是完全锁定执行,防止干扰*/ if(!s.flag){ /*为true则获取值,显示在界面*/ try { s.wait(); /*解锁+等待...*/ } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(s.name + "---" + s.age); s.flag = false; /*使用完成后就修改,保证SetThread运行.*/ s.notify(); /*唤醒GetThread=唤醒...*/}}}}class SetThread implements Runnable { private Student s; private int x = 0; public SetThread(Student s) { this.s = s; } @Override public void run() { while (true) { synchronized (s) { /*锁定局部,而实际造成的结果是完全锁定执行,防止干扰*/ if(s.flag){ /*为flase执行赋值操作...*/ try { s.wait(); /*解锁+等待...*/ } catch (InterruptedException e) { e.printStackTrace(); } } if (x % 2 == 0) { s.name = "Five"; s.age = 5; } else { s.name = "Six"; s.age = 6; } x++; s.flag = true; /*使用完成后就修改,保证GetThread运行.*/ s.notify(); /*唤醒GetThread=唤醒..*/}}}}public class TestFiles { public static void main(String[] args) { Student s = new Student(); SetThread st = new SetThread(s); GetThread gt = new GetThread(s); Thread t1 = new Thread(st); Thread t2 = new Thread(gt); t1.start(); t2.start(); }}
经典的互斥同步-生产消费问题
描述:假设消费者生产者使用一个容器,生产者将产品生产到容器中,消费者将容器中的产品拿出来消费。
程序进入后需要首先检测信号量,判断是否容器存在产品,若不存在,生产者互斥占有并且生产产品放至容器,然后退出互斥占有状态,关闭锁。保证消费者可以获取容器并且使用,消费者使用使用时设置互斥锁锁定使用,使用完成返回容器,放开互斥锁。并设置信号量,保证自己不占有为空的容器,导致死锁。
Code - 互斥同步
/*for example*/上代码结构: - 设置对象简单具体类,是为了使用共享boolean变量,和设置/获取方法。 - 设置互斥设置名字 <=> 生产者互斥同步生产产品. - 设置互斥获取名字 <=> 消费者互斥同步消费产品. - 主函数,调用两个线程:互斥设置&互斥共享线程。 - 创建两个对象,进行类似生产消费操作code。 package CompareTools;class Student { String name; int age; boolean flag;}class GetThread implements Runnable { private Student s; public GetThread(Student s) { this.s = s; } @Override public void run() { while (true) { synchronized (s) { /* 锁定局部,而实际造成的结果是完全锁定执行,防止干扰 */ if (!s.flag) { /* 为true则获取值,显示在界面 */ try { s.wait(); /* 解锁+等待... */ } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+ s.name + "---" + s.age); s.flag = false; /* 使用完成后就修改,保证SetThread运行. */ s.notify(); /* 唤醒GetThread=唤醒... */ } } }}class SetThread implements Runnable { private Student s; private int x = 0; public SetThread(Student s) { this.s = s; } @Override public void run() { while (true) { synchronized (s) { /* 锁定局部,而实际造成的结果是完全锁定执行,防止干扰 */ if (s.flag) { /* 为flase执行赋值操作... */ try { s.wait(); /* 解锁+等待... */ } catch (InterruptedException e) { e.printStackTrace(); } } if (x % 2 == 0) { s.name = "Five"; s.age = 5; } else { s.name = "Six"; s.age = 6; } System.out.println(Thread.currentThread().getName()); x++; s.flag = true; /* 使用完成后就修改,保证GetThread运行. */ s.notify(); /* 唤醒GetThread=唤醒.. */ } } }}public class TestFiles { public static void main(String[] args) { Student s = new Student(); SetThread st = new SetThread(s); GetThread gt = new GetThread(s); Thread t1 = new Thread(st, "st"); Thread t2 = new Thread(gt, "gt"); t1.start(); t2.start(); System.out.println("------this is a dividing line------"); Student ss = new Student(); SetThread stt = new SetThread(ss); GetThread gtt = new GetThread(ss); Thread t11 = new Thread(stt, "stt"); Thread t22 = new Thread(gtt, "gtt"); t11.start(); t22.start(); }}
运行结果:
运行结果一:
运行结果二:
改进的生产者消费者Code
/*for example*//*Tips:添加生产消费过程,方面查看逻辑,同时存在第二次运行可能存在3比2先走,只需要清理控制台,等几秒钟再执行即可,因为Java没有指针不能操作内存,而自动回收机制效率不高。*/package CompareTools;class Student { String name = "Products"; /*flag判断的是容器是否存在商品,存在true;不存在false.*/ boolean flag = false;}class GetThread implements Runnable { private Student s; public GetThread(Student s) { this.s = s; } @Override public void run() { while (true) { if (s.flag) { /*有成品則消費.*/ synchronized (s) { /* 锁定局部互斥消费,防止干扰 */ System.out.println(Thread.currentThread().getName()+"expensing "+ s.name); s.flag = false; /* 使用完成后就修改,保证生产者运行. */ s.notify(); /* 唤醒GetThread=唤醒... */ } } } }}class SetThread implements Runnable { private Student s; private int x = 0; public SetThread(Student s) { this.s = s; } @Override public void run() { while (true) { if (!s.flag) { /*没有产品则生产产品。*/ synchronized (s) { /* 锁定局部互斥生产,防止干扰 */ if (x % 2 == 0) { s.name = "CellPhone-2"; } else { s.name = "Pad-3"; } System.out.println(Thread.currentThread().getName()+"Producting: " + s.name );// result:two x++; s.flag = true; /* 使用完成后就修改,保证消费者运行. */ s.notify(); /* 唤醒GetThread=唤醒...*/ } } } }}public class TestFiles { public static void main(String[] args) { Student s = new Student(); SetThread st = new SetThread(s); GetThread gt = new GetThread(s); Thread t1 = new Thread(st, "ThreadOneSet: "); Thread t2 = new Thread(gt, "ThreadOneGet: "); t1.start(); t2.start(); System.out.println("------this is a dividing line------"); Student ss = new Student(); SetThread stt = new SetThread(ss); GetThread gtt = new GetThread(ss); Thread t11 = new Thread(stt, "ThreadTwoSet: "); Thread t22 = new Thread(gtt, "ThreadTwoGet: "); t11.start(); t22.start(); }}
线程池
线程池,工具类,所有函数均由static修饰。
常用函数Code如下:
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;class MyRunnable implements Runnable{ public void run() { for (int x = 0; x < 100; x++) { System.out.println(Thread.currentThread().getName() + ":" + x); }}}public class ExecutorsDemo { public static void main(String[] args) { // 创建一个线程池对象,参数为线程个数。 // public static ExecutorService newFixedThreadPool(int nThreads) ExecutorService pool = Executors.newFixedThreadPool(2); // 可以执行Runnable对象或者Callable对象的线程. pool.submit(new MyRunnable()); pool.submit(new MyRunnable()); /*结束线程池,否则不会死亡,等待下一对象来说使用.*/ pool.shutdown(); }}
Callable&executors
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; import java.util.concurrent.Callable;/*Callable:是带泛型的接口,这里指定的泛型其实是call()方法的返回值类型*/@SuppressWarnings("rawtypes")class MyCallable implements Callable { /*Callable JDK1.5*/ @Override public Object call() throws Exception { for (int x = 0; x < 50; x++) { System.out.println(Thread.currentThread().getName() + ":" + x); } return null; }}public class CallableDemo { public static void main(String[] args) { /*创建线程池对象*/ ExecutorService pool = Executors.newFixedThreadPool(2); pool.submit(new MyCallable()); pool.submit(new MyCallable()); pool.shutdown(); }}
Callable&executors->sum.
import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;/* * Sum. */class MyCallable implements Callable{ private int number; public MyCallable(int number) { this.number = number; } @Override public Integer call() throws Exception { int sum = 0; for (int x = 1; x <= number; x++) { sum += x; } return sum; }}public class CallableDemo { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService pool = Executors.newFixedThreadPool(2); Future result_01 = pool.submit(new MyCallable(50)); Future result_02 = pool.submit(new MyCallable(100)); Integer sumOne = result_01.get(); Integer sumTwo = result_02.get(); System.out.println("Sum<50>: " + sumOne); System.out.println("Sum<100>: " + sumTwo); /* 结束线程池. */ pool.shutdown(); }}
匿名内部类&线程的使用
/*for example*//* * 匿名内部类的格式: * new 类名或者接口名() { * 重写方法; * }; * 本质:是该类或者接口的子类对象。 */public class ThreadInner { public static void main(String[] args) { /*继承Thread类来实现多线程*/ /*new Thread(){override Code block}.start();*/ new Thread() { public void run() { for (int x = 0; x < 100; x++) { System.out.println(Thread.currentThread().getName() + ":" + x); } } }.start(); /*实现Runnable接口来实现多线程*/ /*new Thread(override Code block){}.start();*/ new Thread(new Runnable() { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(Thread.currentThread().getName() + ":" + x); } } }) { }.start(); /*更有难度的嵌套,本质上考验到底执行哪一部分.*/ /*new Thread(new Runable()代码块){抽象方法Runable代码块}.start();-按照逻辑顺序,走子类对象部分,也就是new Thread(){override Code block}.start();*/ new Thread(new Runnable() { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println("hello" + ":" + x); } } }) { public void run() { for (int x = 0; x < 100; x++) { System.out.println("world" + ":" + x); } } }.start(); }}
Timer定时器
import java.io.File;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;class DeleteFolder extends TimerTask { @Override public void run() { File srcFolder = new File("其他文件"); deleteFolder(srcFolder); } /*递归删除目录*/ public void deleteFolder(File srcFolder) { File[] fileArray = srcFolder.listFiles(); if (fileArray != null) { for (File file : fileArray) { if (file.isDirectory()) { deleteFolder(file); } else { System.out.println(file.getName() + ":" + file.delete()); } } System.out.println(srcFolder.getName() + ":" + srcFolder.delete()); } }}public class TimerTest { public static void main(String[] args) throws ParseException { Timer t = new Timer(); String s = "10:05 2018/11/11"; SimpleDateFormat sdf = new SimpleDateFormat("HH:mm yyyy/MM/dd"); Date d = sdf.parse(s); t.schedule(new DeleteFolder(), d); }}
转载地址:http://aewiz.baihongyu.com/