[关闭]
@Yano 2016-07-10T23:32:02.000000Z 字数 2344 阅读 2600

Java 多线程技能

Java 多线程


进程和线程

进程

操作系统管理的基本运行单元。

任务管理器

线程

进程中独立运行的子任务。单任务的特点是排队执行(同步),CPU利用率低;多线程技术即为异步,系统的运行效率大大提升。

QQ可以理解为一个进程,其中包括很多线程:

  1. 好友视频线程
  2. 下载文件线程
  3. 传输数据线程

使用多线程

继承Thread类

简单例子:

  1. public class MyThread extends Thread{
  2. @Override
  3. public void run() {
  4. super.run();
  5. System.out.println("MyThread");
  6. }
  7. public static void main(String[] args) {
  8. MyThread myThread = new MyThread();
  9. myThread.start();
  10. System.out.println("运行结束!");
  11. }
  12. }

Thread类的定义:

  1. public class Thread implements Runnable {

实现Runnable接口

因为Java不支持多继承,如果欲创建的线程类已经有一个父类,则不能直接继承Thread类。

  1. public class MyRunnable implements Runnable {
  2. @Override
  3. public void run() {
  4. System.out.println("运行中");
  5. }
  6. public static void main(String[] args) {
  7. Runnable runnable = new MyRunnable();
  8. Thread thread = new Thread(runnable);
  9. thread.start();
  10. System.out.println("运行结束");
  11. }
  12. }

实例变量和线程安全

自定义线程的实例变量,针对其他线程可以有共享非共享之分。

不共享数据

不共享数据

  1. public class MyThread extends Thread {
  2. private int count = 5;
  3. public MyThread(String name) {
  4. super();
  5. this.setName(name);
  6. }
  7. @Override
  8. public void run() {
  9. super.run();
  10. while (count > 0) {
  11. count--;
  12. System.out.println(this.currentThread().getName() + "计算,count=" + count);
  13. }
  14. }
  15. public static void main(String[] args) {
  16. MyThread a = new MyThread("A");
  17. MyThread b = new MyThread("B");
  18. MyThread c = new MyThread("C");
  19. a.start();
  20. b.start();
  21. c.start();
  22. }
  23. }

运行结果:

  1. A计算,count=4
  2. B计算,count=4
  3. A计算,count=3
  4. B计算,count=3
  5. B计算,count=2
  6. B计算,count=1
  7. B计算,count=0
  8. A计算,count=2
  9. A计算,count=1
  10. C计算,count=4
  11. C计算,count=3
  12. C计算,count=2
  13. C计算,count=1
  14. C计算,count=0
  15. A计算,count=0

共享数据

共享数据

  1. public class MyThread extends Thread {
  2. private int count = 5;
  3. @Override
  4. public void run() {
  5. count--;
  6. System.out.println(this.currentThread().getName() + "计算,count=" + count);
  7. }
  8. public static void main(String[] args) {
  9. MyThread myThread = new MyThread();
  10. Thread a = new Thread(myThread, "A");
  11. Thread b = new Thread(myThread, "B");
  12. Thread c = new Thread(myThread, "C");
  13. Thread d = new Thread(myThread, "D");
  14. Thread e = new Thread(myThread, "E");
  15. a.start();
  16. b.start();
  17. c.start();
  18. d.start();
  19. e.start();
  20. }
  21. }

运行结果:不保证顺序

  1. D计算,count=1
  2. B计算,count=3
  3. A计算,count=3
  4. C计算,count=2
  5. E计算,count=0

某些JVM中,i--的操作要分成3步:

  1. 取得原有i值
  2. 计算i-1
  3. 对i进行赋值

如果有多个线程同时访问,那么会出现非线程安全问题。


多个线程间进行同步,加锁-synchronized

  1. @Override
  2. synchronized public void run() {
  3. count--;
  4. System.out.println(this.currentThread().getName() + "计算,count=" + count);
  5. }

结果:

  1. B计算,count=4
  2. A计算,count=3
  3. D计算,count=2
  4. E计算,count=1
  5. C计算,count=0

通过在run方法前加入synchronized关键字,使多个线程在执行run方法时,以排队的方式进行处理。当一个线程调用run前,先判断run方法有没有被上锁。如果上锁,则表明其它线程在调用run方法,必须等其它线程对run方法调用结束后才可以执行run方法。加锁的代码称为互斥区临界区

守护线程

一种特殊的线程,特性有陪伴的含义,当进程中没有非守护线程了,守护线程会自动销毁。

典型的守护线程就是GC-垃圾回收线程

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注