码迷,mamicode.com
首页 > 编程语言 > 详细

Java 多线程基础

时间:2017-10-21 15:25:39      阅读:331      评论:0      收藏:0      [点我收藏+]

标签:tor   设置   nat   let   inter   seconds   timertask   sda   getter   

(转载请标明出处)

一、 多线程概念

二、线程的创建和启动

三、线程的生命周期

四、控制线程

五、线程同步

六、线程通信

七、线程组和未处理的异常

八、线程池

九、线程相关类

十、快速创建两种线程

十一、定时器

 

多线程概念:

技术分享

 

技术分享

技术分享

技术分享

线程的创建和启动:

技术分享

 

public class FirstThread extends Thread {
        
        private int i;
        public void run(){
            for (int i = 0; i < 100; i++) {
                System.out.println(getName()+" "+i);
            }
        }
        public static void main(String[] args) {
            for (int i = 0; i < 100; i++) {
            
                System.out.println(Thread.currentThread().getName()+" "+i);
                if(i==20){
                    new FirstThread().start();
                    new FirstThread().start();
                }
            }
        }
    }

技术分享

技术分享

public class SecondThread implements Runnable {
        
        private int i;
        public void run(){
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName()+" "+i);
            }
        }
      
        public static void main(String[] args) {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName()+" "+i);
                if(i==20){
                    SecondThread st = new SecondThread();
                    //通过new Thread(target , name)方法创建新线程
                    new Thread(st,"新线程1").start();
                    new Thread(st,"新线程2").start();
                }
            }
        }
    }

技术分享

技术分享

技术分享

     ExecutorService es = Executors.newFixedThreadPool(2);

        Future<Integer> f1 = es.submit(newMyCallable(10));

        Future<Integer> f2  = es.submit(new MyCallable(20));

        System.out.println(f1.get()+" "+ f2.get());

        es.shutdown();

技术分享

FutureTask<Integer> ft = new FutureTask<Integer>(new MyCallable(10));

        FutureTask<Integer> ft2 = new FutureTask<Integer>(new MyCallable(20));

        new Thread(ft,"我是线程1").start();

        new Thread(ft2,"我是线程2").start();

        System.out.println(ft.get());

技术分享

public class ThirdThread {            
            public static void main(String[] args){
                //创建Callable对象
                ThirdThread rt = new ThirdThread();
                //使用Lambda表达式创建Callable<Integer>对象
                //使用FutureTask来包装Callable对象
                FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)() ->{
                    int i = 0;
                    for(; i < 100; i++){
                        System.out.println(Thread.currentThread().getName() + "i值:"+ i);
                    }
                    //call()方法可以有返回值
                    return i;
                });
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName()+"i值:"+ i);
                    if(i==20){
                        //实质还是以Callable对象来创建并启动线程的
                        new Thread(task,"有返回值的线程").start();
                    }
                }
                try {
                    System.out.println("子线程的返回值"+ task.get());
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }

 

技术分享

 

线程的生命周期:

技术分享

技术分享

技术分享

技术分享

技术分享

技术分享

 

控制线程:

技术分享

 

public class JoinThread extends Thread{
            
            public JoinThread(String name){
                super(name);
            }
            
            public void run(){
                for (int i = 0; i < 100; i++) {
                    System.out.println(getName() + " " +i);
                }
            }
            
            public static void main(String[] args) throws InterruptedException{
                
                new JoinThread("新线程").start();
                for (int i = 0; i < 100; i++) {
                    if(i == 20){
                        //当i==20时 jt开始启动,main线程阻塞
                        JoinThread jt = new JoinThread("被Join的线程");
                        jt.start();
                        //main线程调用了jt线程的join()方法,main线程必须等到jt执行结束
                        //才会向下执行
                        jt.join();
                    }
                    System.out.println(Thread.currentThread().getName() + " " +i);
                }
            }
        }

技术分享

public class DaemonThread extends Thread{
        //后台线程的线程执行体与普通线程没有任何区别
        public void run(){
            for (int i = 0; i < 1000; i++) {
                System.out.println(getName() + " " +i);
            }
        }
        
        public static void main(String[] args) throws InterruptedException{
            
            DaemonThread dt = new DaemonThread();
            dt.setDaemon(true);
            dt.start();
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+" "+i);
            }
            //----------程序执行到此,前台线程main线程结束------------
            //后台线程也随之结束
        }
    }

 

 

技术分享

 

技术分享

技术分享

public class PriorityTest extends Thread{
        
        public PriorityTest(String name){
            super(name);
        }
        
        public void run(){
            for (int i = 0; i < 50; i++) {
                System.out.println(getName() + "优先级:" +getPriority()+" i:"+i);
            }
        }
        
        public static void main(String[] args) throws InterruptedException{
            
            //改变主线程的优先级
            Thread.currentThread().setPriority(6);
            for (int i = 0; i < 30; i++) {
    
                if(i == 10){
                    PriorityTest pt1 = new PriorityTest("低级");
                    pt1.start();
                    System.out.println("创建时的优先级:"+pt1.getPriority()+" i:"+i);
                    pt1.setPriority(MIN_PRIORITY);
                }
                if(i == 20){
                    PriorityTest pt2 = new PriorityTest("高级");
                    pt2.start();
                    System.out.println("创建时的优先级"+pt2.getPriority()+" i:"+i);
                    pt2.setPriority(MAX_PRIORITY);
                }
            }
        }
    }

技术分享

线程同步:

 

技术分享

 

技术分享

技术分享

技术分享

public class DrawThread extends Thread{
            //模拟用户账户
            private Account account;
            //当前取钱线程所希望的取的钱数
            private double drawAmount;
            public DrawThread(String name,Account account,double drawAmount){
                super(name);
                this.account = account;
                this.drawAmount = drawAmount;
            }
            //当多个线程修改同一个共享数据时,将涉及数据安全问题
            public void run(){
                account.draw(drawAmount);
            }
            
            public static void main(String[] args) throws InterruptedException{
                Account acct = new Account("123456",1000);
                new DrawThread("甲",acct,800).start();
                new DrawThread("乙",acct,800).start();
            }
        }
        
        class Account{
            private String accountNo;
            private double balance;
            public Account(){}
            
            public Account(String accountNo, double balance){
                this.accountNo = accountNo;
                this.balance = balance;
            }
            public String getAccountNo() {
                return accountNo;
            }
            public void setAccountNo(String accountNo) {
                this.accountNo = accountNo;
            }
            //因为账户余额不允许随便修改,所以只为balance提供getter方法
            public double getBalance() {
                return balance;
            }
            //提供一个线程安全的draw()方法来完成取钱操作
            public synchronized void draw(double drawAmount){
                if(balance >= drawAmount){
                    System.out.println(Thread.currentThread().getName()+"取钱成功"+drawAmount);
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    balance -= drawAmount;
                    System.out.println("\t余额:"+balance);
                }else{
                    System.out.println(Thread.currentThread()+"取钱失败");
                }
            }
        }

技术分享

同步锁(Lock):

技术分享

 

public class test02 {
            
                private final ReentrantLock lock = new ReentrantLock();
                
                public void m(){
                    //加锁
                    lock.lock();
                    try{
                            //需要保证线程安全的代码
                            //...
                    }
                    //使用finally块来保证释放锁
                    finally{
                        lock.unlock();
                    }
                }
            }

技术分享

技术分享

public class DeadLock implements Runnable {
            
            A a = new A();
            B b = new B();
            public void init(){
                Thread.currentThread().setName("主线程");
                a.foo(b);
                System.out.println("进入主线程");
            }
            public void run(){
                Thread.currentThread().setName("副线程");
                b.bar(a);
                System.out.println("进入副线程之后");
            }
            public static void main(String[] args) {
                DeadLock dl = new DeadLock();
                new Thread(dl).start();
                dl.init();
            }
        
        }
        class A{
            public synchronized void foo(B b){
                System.out.println("当前线程名:"+Thread.currentThread().getName()+"进入A实例的foo()方法");
                
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("当前线程名:"+Thread.currentThread().getName()+"企图调用B实例的last()方法");
                b.last();
            }
            public synchronized void last(){
                System.out.println("进入A类的last()方法内部");
            }        
        }
        class B{
            public synchronized void bar(A a){
                System.out.println("当前线程名:"+Thread.currentThread().getName()+"进入B实例的bar()方法");
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("当前线程名:"+Thread.currentThread().getName()+"企图调用A实例的last()方法");
                a.last();
            }
            public synchronized void last(){
                System.out.println("进入了B类的last()方法内部");
            }
        }

技术分享

public class DeadLockDemo {
        
            public static void main(String[] args) {
                
                new Thread( new DeadLock(false)).start();
                new Thread(new DeadLock(true)).start();
            }
        
        }
        class DeadLock implements Runnable{
            private static final Object objA = new Object();
            private static final Object objB = new Object();
            
            private boolean flag;
            
            public DeadLock(boolean flag){
                this.flag = flag;
            }
            
            @Override
            public void run() {
                while(true){
                    if(flag){
                        synchronized(objA){
                            System.out.println("if objA");
                            
                            synchronized(objB){
                                System.out.println("if objB");
                            }
                        }
                    }else{
                        synchronized(objB){
                            System.out.println("else objB");
                            synchronized(objA){
                                System.out.println("else objA");
                            }
                        }
                    }
                }
            }
        }

线程通信:

技术分享

 

技术分享

public class DrawTest {
            
            public static void main(String[] args) {
                //创建一个账户
                Account acct = new Account("123",0);
                new DrawThread("取钱者",acct,800).start();
                new DepositThread("存钱者1", acct, 800).start();
                new DepositThread("存钱者2", acct, 800).start();
                new DepositThread("存钱者3", acct, 800).start();
            }
        }
        
        class Account{
            private String accountNo;
            private double balance;
            //标识账户中是否已经有存款的旗标
            private boolean flag = false;
            public Account(){}
            
            public Account(String accountNo, double balance){
                this.accountNo = accountNo;
                this.balance = balance;
            }
        
            public String getAccountNo() {
                return accountNo;
            }
        
            public void setAccountNo(String accountNo) {
                this.accountNo = accountNo;
            }
        
            //因为账户余额不允许随便修改,所以只为balance提供getter方法
            public double getBalance() {
                return balance;
            }
            
            //提供一个线程安全的draw()方法来完成取钱操作
            public synchronized void draw(double drawAmount){
                try {
                    if(!flag){
                        wait();
                    }else{
                        //执行取钱操作
                        System.out.println(Thread.currentThread().getName()+"取钱"+drawAmount);
                        balance -= drawAmount;
                        System.out.println("账户余额为:"+balance);
                        flag = false;
                        //唤醒其他线程
                        notifyAll();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            
            public synchronized void deposit(double depositAmount){
                try {
                    //flag为true 表示账户已有人存钱进去,存钱方法阻塞
                    //当while判断后,wait()方法释放锁,唤醒其他线程去存钱,当存取次数相同时,此程序不会阻塞
        //            while(flag){
        //                wait();
        //            }
                    if(flag){
                        wait();
                    }else{
                        //执行存款操作
                        System.out.println(Thread.currentThread().getName()+"存款:"+ depositAmount);
                        balance += depositAmount;
                        System.out.println("账户余额:"+balance);
                        flag = true;
                        notifyAll();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        class DrawThread extends Thread{
            //模拟用户取钱
            private Account account;
            //当前取钱线程所希望取的钱数
            private double drawAmount;
            public DrawThread(String name,Account account,double drawAmount){
                super(name);
                this.account = account;
                this.drawAmount = drawAmount;
            }
            public void run(){
                for (int i = 0; i < 300; i++) {
        
                    System.out.println("取钱次数"+i);
                    account.draw(drawAmount);
                }
            }
        }
        
        class DepositThread extends Thread{
            //模拟用户账户
            private Account account;
            //当前存钱线程所希望存的钱数
            private double depositAmount;
            public DepositThread(String name , Account account , double depositAmount){
                super(name);
                this.account = account;
                this.depositAmount = depositAmount;
            }
            public void run(){
                for (int i = 0; i < 100; i++) {
                    account.deposit(depositAmount);
                }
            }
        }

技术分享

技术分享

class Account{
            
            //显示定义Lock对象
            private final Lock lock = new ReentrantLock();
            //获得指定Lock对象对应的Condition
            private final Condition cond = lock.newCondition();
            
            private String accountNo;
            private double balance;
            //标识账户中是否已经有存款的旗标
            private boolean flag = false;
            public Account(){}
            
            public Account(String accountNo, double balance){
                this.accountNo = accountNo;
                this.balance = balance;
            }
        
            public String getAccountNo() {
                return accountNo;
            }
        
            public void setAccountNo(String accountNo) {
                this.accountNo = accountNo;
            }
        
            //因为账户余额不允许随便修改,所以只为balance提供getter方法
            public double getBalance() {
                return balance;
            }
            
            //提供一个线程安全的draw()方法来完成取钱操作
            public  void draw(double drawAmount){
                lock.lock();
                try {
                    if(!flag){
                        cond.await();
                    }else{
                        //执行取钱操作
                        System.out.println(Thread.currentThread().getName()+"取钱"+drawAmount);
                        balance -= drawAmount;
                        System.out.println("账户余额为:"+balance);
                        flag = false;
                        //唤醒其他线程
                        cond.signalAll();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                finally{
                    lock.unlock();
                }
            }
            
            
            public  void deposit(double depositAmount){
                lock.lock();
                try {
                    //flag为true 表示账户已有人存钱进去,存钱方法阻塞
                    //当while判断后,wait()方法释放锁,唤醒其他线程去存钱,当存取次数相同时,此程序不会阻塞
        //            while(flag){
        //                wait();
        //            }
                    if(flag){
                        cond.await();
                    }else{
                        //执行存款操作
                        System.out.println(Thread.currentThread().getName()+"存款:"+ depositAmount);
                        balance += depositAmount;
                        System.out.println("账户余额:"+balance);
                        flag = true;
                        cond.signalAll();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                finally{
                    lock.unlock();
                }
            }
        }
        
        class DrawThread extends Thread{
            //模拟用户取钱
            private Account account;
            //当前取钱线程所希望取的钱数
            private double drawAmount;
            public DrawThread(String name,Account account,double drawAmount){
                super(name);
                this.account = account;
                this.drawAmount = drawAmount;
            }
            public void run(){
                for (int i = 0; i < 300; i++) {
        
                    System.out.println("取钱次数"+i);
                    account.draw(drawAmount);
                }
            }
        }

技术分享

技术分享

技术分享

public class BlockingQueueTest {
        
            public static void main(String[] args) {
                //创建一个容量为1的BlockingQueue
                BlockingQueue<String> bq = new ArrayBlockingQueue<>(1);
                //产生3个生产者线程
                new Producer(bq).start();
                new Producer(bq).start();
                new Producer(bq).start();
                //启动一个消费者线程
                new Consumer(bq).start();
            }
            
        }
        
        class Producer extends Thread{
            private BlockingQueue<String> bq;
            public Producer(BlockingQueue<String> bq){
                this.bq = bq;
            }
            public void run(){
                String[] strArr = new String[]{"Java","Struts","Spring"};
                for (int i = 0; i < 999999999; i++) {
                    System.out.println(getName() + "生产者准备生产集合元素");
                    //尝试放入元素,如果队列已满,则线程被阻塞
                    try {
                        Thread.sleep(200);
                        bq.put(strArr[i % 3]);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName()+"生产完成"+bq);
                }
            }
        }
        
        class Consumer extends Thread{
            private BlockingQueue<String> bq;
            public Consumer(BlockingQueue<String> bq){
                this.bq = bq;
            }
            public void run(){
                while(true){
                    System.out.println(getName() + "消费者准备消费集合元素!");
                    try {
                        Thread.sleep(200);
                        bq.take();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName()+"消费完成"+bq);
                }
            }
        }

 

线程组和未处理的异常:

 

技术分享

 

技术分享

技术分享

技术分享

public class ThreadGroupTest {
    
        public static void main(String[] args) {
            //获取主线程所在的线程组,这是所有线程默认的线程组
            ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
            System.out.println("主线程祖的名字:"+mainGroup.getName());
            System.out.println("主线程是否是后台线程组"+mainGroup.isDaemon());
            new MyThread("主线程组的线程").start();
            
            ThreadGroup tg = new ThreadGroup("新线程组");
            tg.setDaemon(true);
            System.out.println("tg线程组是否是后台线程组"+tg.isDaemon());
            MyThread tt = new MyThread(tg,"tg线程甲");
            tt.start();
            new MyThread(tg,"tg组的线程乙").start();
        }
    
    }
    class MyThread extends Thread{
        //提供指定线程名的构造器
        public MyThread(String name){
            super(name);
        }
        //提供指定线程名、线程组的构造器
        public MyThread(ThreadGroup group , String name){
            super(group,name);
        }
        public void run(){
            for (int i = 0; i < 20; i++) {
                System.out.println(getName() + "线程的i变量"+i);
            }
        }
    }

 

技术分享

技术分享

public class ExHandler {
        
            public static void main(String[] args) {
                //设置主线程的异常处理器
                Thread.currentThread().setUncaughtExceptionHandler(new MyExHandler());
                int a = 5/0;
                System.out.println("线程正常结束");
        
            }
        }
        class MyExHandler implements Thread.UncaughtExceptionHandler{
        
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println(t+"线程出现了异常:"+e);
            }
        }

 

技术分享

线程池:

技术分享

 

技术分享

技术分享

技术分享

 

public class ThreadPoolTest {
        
            public static void main(String[] args) throws Exception{
                //创建一个具有固定线程数6的线程池
                ExecutorService pool = Executors.newFixedThreadPool(6);
                //使用lambda表达式创建Runnable对象
                Runnable target = () -> {
                    for (int i = 0; i < 100; i++) {
                        System.out.println(Thread.currentThread().getName()+"i值:"+i);
                    }
                };
                //向线程池中提交两个线程
                pool.submit(target);
                pool.submit(target);
                //关闭线程池
                pool.shutdown();
            }
        }

 

技术分享

技术分享

public class ForkJoinPoolTest {
        
            public static void main(String[] args) throws Exception {
                ForkJoinPool pool = new ForkJoinPool();
                //提交可分解的PrintTask任务
                pool.submit(new PrintTask(0,300));
                pool.awaitTermination(2, TimeUnit.SECONDS);
                //关闭线程池
                pool.shutdown();
            }
        
        }
        class PrintTask extends RecursiveAction{
        
        
            private static final long serialVersionUID = 1L;
            //每个“小任务”最多打印50个数
            private static final int THRESHOLD = 50;
            private int start;
            private int end;
            //打印从start到end的任务
            public  PrintTask(int start,int end){
                this.start = start;
                this.end = end;
            }
            
            @Override
            protected void compute() {
                //当end与start之间的差小于THRESHOLD时,开始打印
                if(end - start < THRESHOLD){
                    for (int i = start ; i < end; i++) {
                        System.out.println(Thread.currentThread().getName()+"i的值:"+i);
                    }
                }else{
                    //当end与start之间的差大于Threshold,即要打印的数超过50个时
                    //将大任务分解成两个”小任务“
                    int middle = (start + end)/2;
                    PrintTask left = new PrintTask(start, middle);
                    PrintTask right = new PrintTask(middle, end);
                    //并行执行两个”小任务“
                    left.fork();
                    right.fork();
                }
            }
            
        }

 

技术分享

public class Sum {
        
            public static void main(String[] args) throws Exception{
                int[] arr = new int[100];
                Random rand = new Random();
                int total = 0;
                //初始化100个数字元素
                for (int i = 0,len = arr.length; i < len; i++) {
                    int tmp = rand.nextInt(20);
                    //对数组的元素赋值,并将数组元素的值添加到sum总和中
                    total += (arr[i] = tmp);
                    System.out.println(arr[i]);
                }
                System.out.println(total);
                //创建一个通用池
                ForkJoinPool pool = ForkJoinPool.commonPool();
                //提交可分解的CaltTask任务
                Future<Integer> future = pool.submit(new CalTask(arr,0,arr.length));
                System.out.println(future.get());
                //关闭线程池
                pool.shutdown();
            }
        
        }
        class CalTask extends RecursiveTask<Integer>{
            
            //每个"小任务"最多只累加20个数
            private static final int THRESHOLD = 20;
            private int arr[];
            private int start;
            private int end;
            //累加从start到end的数组元素
            public CalTask(int[] arr , int start , int end){
                this.arr = arr;
                this.start = start;
                this.end = end;
            }
            
            @Override
            protected Integer compute() {
                int sum = 0;
                //当end 与 start 之间的差小于THRESHOLD时,开始进行累加
                if(end - start < THRESHOLD){
                    for(int i = start; i < end ;i++){
                        sum += arr[i];
                    }
                    return sum;
                }else{
                    //当end与start之间的差大于THRESHOLD,即要累加的数超过20个小时
                    //将大任务分解成两个"小任务"
                    int middle = (start + end) /2;
                    CalTask left = new CalTask(arr,start,middle);
                    CalTask right = new CalTask(arr,middle,end);
                    //并行执行两个"小任务"
                    left.fork();
                    right.fork();
                    //把两个"小任务"累加的结果合并起来
                    return left.join() + right.join();
                }
            }
        }

 

线程相关类:

 技术分享

技术分享

public class ThreadLocalTest {
        
            public static void main(String[] args) {
                //启动两个线程,两个线程共享一个TAccount
                TAccount at = new TAccount("初始名");
                /**
                 * 虽然两个线程共享一个账户,即只有一个账户名
                 * 但由于账户名是ThreadLocal类型的,所以每个线程都完全拥有
                 * 各自的账户名副本。因此在i==6之后,将看到两个线程访问同一个
                 * 账户时出现不同的账户名
                 */
                new MyTest(at,"线程甲").start();
                new MyTest(at,"线程乙").start();
            }
        }
        class TAccount{
            //定义一个ThreadLocal类型的变量,该变量将是一个线程局部变量
            //每个线程都会保留该变量的一个副本
            private ThreadLocal<String> name = new ThreadLocal<String>();
            //定义一个初始化name成员变量的构造器
            public TAccount(String str){
                this.name.set(str);
                System.out.println("-----" + this.name.get());
            }
            public String getName() {
                return name.get();
            }
            public void setName(String str) {
                this.name.set(str);;
            }
            
        }
        class MyTest extends Thread{
            //定义一个Account类型的成员变量
            private TAccount account;
            public MyTest(TAccount account , String name){
                super(name);
                this.account = account;
            }
            public void run(){
                //循环10次
                for (int i = 0; i < 10; i++) {
                    //当i==6时输出将账户名替换成当前线程名
                    if(i==6){
                        account.setName(getName());
                    }
                    //输出同一个账户的账户名和循环变量
                    System.out.println(account.getName()+" 账户的i值  "+i);
                }
            }
        }

 

 

技术分享

 

技术分享

技术分享

技术分享

快速创建两种线程:

 

public class Test00 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //第一种:
        new Thread("我是线程1"){
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName()+" "+i);
                }
            }
        }.start();
        
        
        
        //第二种:
        new Thread(new Runnable(){  //匿名内部类的实质是创建该类或接口的子类对象
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName()+" "+i);
                }
            }
        },"我是线程2").start();
    }

}

 

 

定时器:

技术分享

 

技术分享

技术分享

/**
     * 需求:在指定时间删除指定目录
     * @author 
     *
     */
    public class TimerDemo {
        
        public static void main(String[] args) throws ParseException {
            Timer t = new Timer();
            
            String s = "2017-8-15 9:42:00";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date d = sdf.parse(s);
            
            t.schedule(new DeleteFolder(),d);
        }
    
    }
    
    class DeleteFolder extends TimerTask{
    
        @Override
        public void run() {
            File srcFolder = new File("demo");
            deleteFolder(srcFolder);
        }
        //递归删除目录
        public void deleteFolder(File srcFolder){
            File[] fileArr = srcFolder.listFiles();
            if(fileArr != null){
                for(File file:fileArr){
                    if(file.isDirectory()){
                        deleteFolder(file);
                    }else{
                        System.out.println(file.getName()+":"+file.delete());
                    }
                }
                System.out.println(srcFolder.getName()+":"+srcFolder.delete());
            }
        }
    }

 

Java 多线程基础

标签:tor   设置   nat   let   inter   seconds   timertask   sda   getter   

原文地址:http://www.cnblogs.com/dweeb/p/7696732.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!