mysql 多线程 demo_多线程(示例代码)

1 线程与进程:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。多线程即一个程序中有多个线程在同时执行。

2 多线程调度模式:

分时调度:所有线程轮流使用CPU,平均分配每个线程占用CPU的时间。

抢占式调度:优先级高的线程优先使用CPU,优先级相同,随机选择一个(线程随机性),Java使用的为抢占式调度。

抢占式调度在多个线程间高速切换。对于CPU的一个核而言,某个时刻只能执行一个线程,而 CPU在多个线程间切换速度很快,感觉像是在同一时刻运行。多线程并不能提高   运行速度,但能提高运行效率,让CPU的使用率更高。

3 主线程:JVM启动后,主线程从main方法开始,一直到main方法结束。

4 创建新线程的方法:

①定义一个类继承Thread类,该子类重写Thread类的 run方法。创建子类对象,即创建线程对象,调用start方法,开启线程并让线程执行,同时还会告诉jvm去调用run方法。

1 //自定义测试类

2 public classDemo01 {3 public static voidmain(String[] args) {4 //创建自定义线程对象

5 MyThread mt = newMyThread();6 //开启新线程

7 mt.start();//线程对象调用start开启线程,并让jvm调用run方法在开启的线程中执行。调用run方法不开启线程,只是调用对象的方法。8 //在主方法中执行for循环

9 for (int i = 0; i < 10; i++) {10 System.out.println("main线程!"+i);11 }12 }13 }14 //自定义线程类

15 public class MyThread extendsThread {16 //定义指定线程名称的构造方法

17 publicMyThread(String name) {18 //调用父类的String参数的构造方法,指定线程的名称

19 super(name);20 }21 /**

22 * 重写run方法,完成该线程执行的逻辑23 */

24 @Override25 public voidrun() {26 for (int i = 0; i < 10; i++) {27 System.out.println(getName()+":正在执行!"+i);28 }29 }30 }

为什么要继承Thread类,并调用其start方法才能开启线程呢?

继承Thread类:因为Thread类用来描述线程,具备线程应该有功能。直接mt.run();是直接调用了MyThread对象的run方法,重写的run方法执行了,但没有开启多线程。

那为什么不直接创建Thread类的对象呢?如下代码:

Thread t1 = new Thread();

t1.start();

这样做没有错,但是该start调用的是Thread类中的run方法而不是我们创建的MyThread类中的run方法,这个run方法并没有我们需要让线程执行的代码。

②声明一个类,实现Runnable接口。该类实现run方法。创建Runnable的子类对象,new一个新Thread对象,将Runnable子类对象传入到新Thread的构造方法中,开启线程。

1 //测试类

2 public classDemo02 {3 public static voidmain(String[] args) {4 //创建线程执行目标类对象

5 Runnable runn = newMyRunnable();6 //将Runnable接口的子类对象作为参数传递给Thread类的构造函数

7 Thread thread = newThread(runn);8 Thread thread2 = newThread(runn);9 //开启线程

10 thread.start();11 thread2.start();12 for (int i = 0; i < 10; i++) {13 System.out.println("main线程:正在执行!"+i);14 }15 }16 }17 //自定义线程执行任务类

18 public class MyRunnable implementsRunnable{19

20 //定义线程要执行的run方法逻辑

21 @Override22 public voidrun() {

24 for (int i = 0; i < 10; i++) {25 System.out.println("我的线程:正在执行!"+i);26 }27 }28 }

实现Runnable的好处:

第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。实现runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。Runnable接口对线程对象和线程任务进行解耦。

5 多线程内存分配:每创建一个新线程都会开辟一个新的栈内存空间,线程任务结束释放栈内存。

6 获取线程的名称:Thread.currentThread().getName();(原来主线程的名称:main;自定义的线程:Thread-0,多个线程时,数字顺延。如Thread-1......)

7 多线程设置名称:测试类中mt.setName("xxx");或者MyThread类中super("xxx");调用父类构造器。一般情况不需要设置名称。

8 多线程内使用匿名内部类:

1 //方式1:创建线程对象时,直接重写Thread类中的run方法

2 newThread() {3 public voidrun() {4 for (int x = 0; x < 40; x++) {5 System.out.println(Thread.currentThread().getName() + "...X...." +x);6 }7 }8 }.start();9

10 //方式2:使用匿名内部类的方式实现Runnable接口,重新Runnable接口中的run方法

11 Runnable r = newRunnable() {12 public voidrun() {13 for (int x = 0; x < 40; x++) {14 System.out.println(Thread.currentThread().getName() + "...Y...." +x);15 }16 }17 };18 new Thread(r).start();

9 线程池及作用:线程池,容纳多个线程的容器,其中的线程可以反复使用,省去了创建线程对象的操作,无需反复创建线程而消耗过多资源。

在java中,创建/销毁线程消耗的时间和系统资源都很大,甚至可能要比在处理用户请求的时间和资源要多。运行中的线程也占用系统资源,如果在一个jvm里创建太多的线程,可能会使系统由于过度消耗内存或“切换过度”而导致系统资源不足。

10 使用线程池的方式:

①Runnable接口

Executors:线程池创建工厂类

public static ExecutorService newFixedThreadPool(int nThreads):返回线程池对象

ExecutorService:线程池类

Future> submit(Runnable task):获取线程池中的某一个线程对象,并执行

Future接口:用来记录线程任务执行完毕后产生的结果。

使用线程池中线程对象的步骤:

1创建线程池对象

2创建Runnable接口子类对象

3提交Runnable接口子类对象

4关闭线程池

1 //测试类

2 public classThreadPoolDemo {3 public static voidmain(String[] args) {4 //1创建线程池对象

5 ExecutorService service = Executors.newFixedThreadPool(2);//包含2个线程对象6 //2创建Runnable子类对象

7 MyRunnable r = newMyRunnable();8

9 //自己创建线程对象的方式10 //Thread t = new Thread(r);11 //t.start(); ---> 调用MyRunnable中的run()12

13 //3提交Runnable接口子类对象

14 service.submit(r);15 //再获取个线程对象,调用MyRunnable中的run()

16 service.submit(r);17 service.submit(r);18 //注意:submit方法调用结束后,程序并不终止,是因为线程池控制了线程的关闭。将使用完的线程又归还到了线程池中19

20      //关闭线程池21 //service.shutdown();

22 }23 }24 //Runnable接口实现类:略

②Callable接口

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

ExecutorService:线程池类

Future submit(Callable task):获取线程池中的某一个线程对象,并执行线程中的call()方法

Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用

使用线程池中线程对象的步骤:

1创建线程池对象

2创建Callable接口子类对象

3提交Callable接口子类对象

4关闭线程池

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值