java多线程

多线程:

进程和线程的区别

区别

进程

线程

根本区别

作为资源分配的单位

调度和执行的单位

开销

每个进程都要独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销

线程可以看出轻量级的进程,每一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器,线程切换的开销小

所处环境

在操作系统中能同时运行多个任务(程序)

在同一应用程序中有多个程序流同时执行

分配内存

系统在运行的时候会为每个内存分配不同的内存区域

出CPU外,不会为线程分配内存,(线程所使用的资源是他所属的进程的资源),线程组只能共享资源

包含关系

没有线程的进程可以看做单线程,如果一个进程有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的

线程是进程的一部分,所以线程有时候被认为是轻权进程或者轻量级进程

 

线程的创建方法

  1. 将类声明为thread的子类,该子类重写thread类的run方法,

New 子类().start;

public class Rabbit extends Thread {

       @Override

       public void run() {

              for(int i = 0;i < 100;i++) {

                     System.out.println("兔子跑了"+i+"步");

              }

       }

}

public class Test {

       public static void main(String[] args) {

              Rabbit r = new Rabbit();

              r.start();

       }

}

  1. 声明实现runnable接口的类,该类然后实现run方法,

Thread t = new Thread(new 实现类());   t.start();

public class Tortoise implements Runnable {

       public void run() {

              for(int i = 0;i < 88;i++) {

                     System.out.println("tortoise run"+i+"step");

              }

       }

}

public class Test {

       public static void main(String[] args) {

              Thread t = new Thread(new Tortoise());

              t.start();

       }

}

  1. 实现Callable接口,重写call方法

用Executors类的静态方法newFixedThreadPool创建线程池,提交新建的线程获取到线程池中的线程

public class CallbaleDemo {

       public static void main(String[] args) throws Exception {

              //创建线程

              ExecutorService service = Executors.newFixedThreadPool(2);

              Future<String> submit = service.submit(new Demo());

              //获取值

              String s = submit.get();

              System.out.println(s);

       }

}

       class Demo implements Callable<String> {

              public String call() {

                     return "你好";

              }

       }

 

 

             

              //线程匿名内部类:节省了代码直接创建线程

             

              //继承方式

              new Thread() {

                     public void run() {

                            System.out.println("!!!");

                     }

              }.start();

             

              //接口方式

              Runnable r = new Runnable() {

                     public void run() {

                            System.out.println("@@@");

                     }

              };

              new Thread(r).start();

             

       }

}

****************************************************************************************

 

线程阻塞join()

public class JoinDemo extends Thread {

 

       public static void main(String[] args) throws InterruptedException {

 

              JoinDemo join = new JoinDemo();

              join.start();

 

              for (int i = 0; i < 100; i++) {

                     System.out.println("main" + i);

                     if (i == 50) {

                            join.join();// main阻塞,等待join运行结束,合并线程

                     }

              }

       }

 

       @Override

       public void run() {

              for (int i = 0; i < 1000; i++) {

                     System.out.println("join--" + i);

              }

       }

}

暂停线程Yield

public class YieldDemo extends Thread {

       public static void main(String[] args) {

              YieldDemo y1 = new YieldDemo();

              y1.start();

              for(int i = 0;i < 100;i++) {

                     System.out.println("main"+i);

                     if(i==50) {

                            Thread.yield();//静态方法写在main中,main休眠

                     }

              }

       }

       public void run() {

              for (int i = 0; i < 1000; i++) {

                     System.out.println("join--" + i);

              }

       }

}

 

任务调度

public class ScheduleDemo {

       public static void main(String[] args) {

              Timer timer = new Timer();

              timer.schedule(new TimerTask() {

                     public void run() {

                            System.out.println("hello world");

                     }

              }, new Date(System.currentTimeMillis()+1000),1000);

              //1秒后间隔1秒执行timetask()中的run()方法

       }

}

 

 

线程的方法及优先级

package info;

 

/*

 * 线程中的几个方法

 * currentThread()     静态方法,获取到当前线程

 * getName()      获取到线程名字

 * setName() 设置线程名字

 * isAlive()    判断线程是否活着

 * setPriority() 设置优先级

 */

public class MyThread implements Runnable {

       private boolean flag = true;

       private int num = 0;

       @Override

       public void run() {

              while(flag) {

                     System.out.println(Thread.currentThread().getName()+"--"+num++);

              }

       }

       //线程停止的方法

       public void stop() {

              this.flag = !this.flag;

       }

}

public class InfoDemo {

       public static void main(String[] args) throws InterruptedException {

              MyThread my = new MyThread();

              Thread t = new Thread(my,"shijie");//构造方法对线程命名

              t.setName("niaho");

              t.start();

              System.out.println(t.isAlive());

             

              String name = Thread.currentThread().getName();

              System.out.println(name);

              Thread.sleep(200);

              my.stop();

              Thread.sleep(2000);

              System.out.println(t.isAlive());

       }

}

public class InfoDemo2 {

       public static void main(String[] args) throws InterruptedException {

              MyThread my1 = new MyThread();

              MyThread my2 = new MyThread();

              Thread t1 = new Thread(my1,"111");

              Thread t2 = new Thread(my2,"222");

              t1.setPriority(Thread.MAX_PRIORITY);

              t2.setPriority(Thread.MIN_PRIORITY);

              t1.start();

              t2.start();

              Thread.sleep(400);

              my1.stop();

              my2.stop();

       }

}

 

线程同步

/*

 * 多线程共用数据时,通过线程休眠出现安全问题

 * 解决方法:java提供同步技术

 *   公式:synchronized(任意对象){

 *                 线程要操作的共享数据

 *          }

 *

 * 线程遇到同步时,判断锁,有,获取锁,出同步时,释放锁, 不出去就不释放别人就是进不来

 *                          判断锁,无,进不去

 * 有同步会导致运行速度下降

 */

public class Tickets implements Runnable{

       private int tickets = 100;

       Object obj = new Object();  //同步随便找的对象

       //线程共享数据保证安全,要加入同步代码块

/*    public void run() {

              while(true) {

                     synchronized (obj) {    

                            if(tickets > 0) {

                                   System.out.println(Thread.currentThread()+"出售"+tickets--);

                            }

                     }

              }

       }*/

       public void run() {

              while(true) {

                     function();

              }

       }

       //同步方法,代码简洁

       //同样有同步锁,同步对象为this 本类的对象引用

       public synchronized void function() {

              if(tickets > 0) {

                     System.out.println(Thread.currentThread()+"出售"+tickets--);

              }

       }

}

package threadDemo2;

 

public class ThreadDemo {

       public static void main(String[] args) {

              Tickets t = new Tickets();

              Thread t0 = new Thread(t);

              Thread t1 = new Thread(t);

              Thread t2 = new Thread(t);

              t0.start();

              t1.start();

              t2.start();

       }

      

}

 

 

 

 

 

线程池;

Runnable接口

  1. 使用线程池中线程对象的步骤:
    1. 创建线程池对象
    2. 创建Runnable接口子类对象
    3. 提交Runnable接口子类对象
    4. 关闭线程池

 

代码演示:

public class ThreadPoolDemo {

    public static void main(String[] args) {

        //创建线程池对象

        ExecutorService service = Executors.newFixedThreadPool(2);//包含2个线程对象

        //创建Runnable实例对象

        MyRunnable r = new MyRunnable();

       

        //自己创建线程对象的方式

        //Thread t = new Thread(r);

        //t.start(); ---> 调用MyRunnable中的run()

       

        //从线程池中获取线程对象,然后调用MyRunnable中的run()

        service.submit(r);

        //再获取个线程对象,调用MyRunnable中的run()

        service.submit(r);

        service.submit(r);

//注意:submit方法调用结束后,程序并不终止,是因为线程池控制了线程的关闭。将使用完的线程又归还到了线程池中

 

//关闭线程池

        //service.shutdown();

    }

}

  1. Runnable接口实现类

public class MyRunnable implements Runnable {

    @Override

    public void run() {

        System.out.println("我要一个教练");

       

        try {

            Thread.sleep(2000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        System.out.println("教练来了: " +Thread.currentThread().getName());

        System.out.println("教我游泳,交完后,教练回到了游泳池");

    }

}

 

Callable接口

  1. Callable接口:与Runnable接口功能相似,用来指定线程的任务。其中的call()方法,用来返回线程任务执行完毕后的结果,call方法可抛出异常。

代码演示:

public class ThreadPoolDemo {

    public static void main(String[] args) {

        //创建线程池对象

        ExecutorService service = Executors.newFixedThreadPool(2);//包含2个线程对象

        //创建Callable对象

        MyCallable c = new MyCallable();

       

        //从线程池中获取线程对象,然后调用MyRunnable中的run()

        service.submit(c);

       

        //再获取个教练

        service.submit(c);

        service.submit(c);

//注意:submit方法调用结束后,程序并不终止,是因为线程池控制了线程的关闭。将使用完的线程又归还到了线程池中

 

//关闭线程池

        //service.shutdown();

    }

}

  1. Callable接口实现类,call方法可抛出异常、返回线程任务执行完毕后的结果

public class MyCallable implements Callable {

    @Override

    public Object call() throws Exception {

        System.out.println("我要一个教练:call");

        Thread.sleep(2000);

        System.out.println("教练来了: " +Thread.currentThread().getName());

        System.out.println("教我游泳,交完后,教练回到了游泳池");

        return null;

    }

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值