Java 多线程
Author: Abbott Liu(刘建)
Education: 加里敦
所谓多线程,就是说一个应用程序有多条执行门路,每当咱们关上一个应用程序的时候,就像当与关上了一个过程,而过程中执行的操作,就是线程。以迅雷为例,关上迅雷就相当于关上一个过程,下载文件的操作就是线程,多线程就是同时下载多个文件
在 Java 中有两种形式实现多线程别离是继承 Thread 类和实现 Runnable 接口
一、继承 Thread 类
Thread 类中有一个 run 办法,然而这个 run 办法须要咱们重写,故咱们须要自定义一个类来继承 Thread 类,而后在自定义的类中重写这个 run 办法,重写完了就能够创立一个对象了,用该对象去调用这个办法,然而因为这是多线程,如果是间接调用 run 办法,无奈实现多线程,而后就有了一个新的的办法 start 办法供咱们应用,此办法会主动调用 run 办法。
代码:
package com.abbott;
class MusicThread extends Thread {public void run() {for (int x = 0; x < 10; x++) {System.out.println(getName() + ":" + x);
}
}
}
public class MultiplyThread {public static void main(String[] args) {
// 创立多线程对象
MusicThread mt1 = new MusicThread();
MusicThread mt2 = new MusicThread();
MusicThread mt3 = new MusicThread();
// 设置每个对象的名字
mt1.setName("abbott");
mt2.setName("liu");
mt3.setName("java");
// 调用 start() 办法,其外部调用了 run() 办法,实现了多线程
// 如果间接调用 run() 办法,不能实现多线程
mt1.start();
mt2.start();
mt3.start();}
}
二、实现 Runnable 接口
为了解决单继承的局限性,因为如果某个类曾经有父亲了,那么它就不能再继承 Thread 来实现多线程了,所以就有了实现接口的多线程,咱们大部分应用的办法也是用接口来实现多线程。接口方式实现多线程咱们须要自定义一个类去实现 Runnable 接口,而后在自定义的类中重写 run 办法,再而后去创立一个自定义类的对象,最初创立一个 Thread 类的对象,并且把刚刚创立的自定义对象作为参数传递。
package com.abbott;
class Father {
private String name = "刘建";
public String getName() {return name;}
}
class MusicThread extends Father implements Runnable {
static int count = 0;
// 公共资源
private int t = 0;
private synchronized void increase() {count++;}
@Override
public void run() {for (int x = 0; x < 100; x++) {increase();
System.out.println(Thread.currentThread().getName() + ":" + count);
// System.out.println(Thread.currentThread().getName() + ":" + t++);
}
}
}
public class MultiplyThread {public static void main(String[] args) throws InterruptedException {
// 创立多线程对象
MusicThread mt = new MusicThread() ;
Thread t1 = new Thread(mt,"abbott");
Thread t2 = new Thread(mt,"liu");
Thread t3 = new Thread(mt,"hello");
// 设置每个对象的名字
t1.start();
t2.start();
t3.start();}
}
三、继承 Thread 类和实现 Runnable 办法的区别
- 继承 Thread 类不适宜资源的共享,而实现 Runnable 接口很容易实现资源的共享
- 实现 Runnable 接口适宜多个雷同的程序代码的线程去解决同一个资源
- 防止了 Java 中的单继承限度
- 加强了程序的健壮性,代码能够被多个线程共享
四、线程延时 sleep()
package com.abbott;
class Father {
private String name = "刘建";
public String getName() {return name;}
}
class MusicThread extends Father implements Runnable {
static int count = 0;
// 公共资源
private int t = 0;
private synchronized void increase() {count++;}
@Override
public void run() {for (int x = 0; x < 100; x++) {increase();
try {Thread.sleep(2000);
} catch (InterruptedException e) {e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + count);
// System.out.println(Thread.currentThread().getName() + ":" + t++);
}
}
}
public class MultiplyThread {public static void main(String[] args) throws InterruptedException {
// 创立多线程对象
MusicThread mt = new MusicThread() ;
Thread t1 = new Thread(mt,"abbott");
t1.start();}
}
五、线程中断 interrupt()
package com.abbott;
class MusicThread extends Thread {public void run() {System.out.println("线程开始");
try {
// 在这里是线程劳动 2 秒,如果线程在 2 秒内被中断,则执行 catch
Thread.sleep(2000);
} catch (InterruptedException e) {// e.printStackTrace();
System.out.println("线程中断");
}
System.out.println("线程完结");
}
}
public class MultiplyThread {public static void main(String[] args) throws InterruptedException {MusicThread mt = new MusicThread();
mt.start();
try {Thread.sleep(1000);
mt.interrupt();// 这里的意思是线程执行如果超过 1 秒就被中断} catch (InterruptedException e) {// e.printStackTrace();
System.out.println("中断线程");
}
}
}
六、线程同步 synchronized()
多线程中,线程同步问题
package com.abbott;
class Father {
private String name = "刘建";
public String getName() {return name;}
}
class MusicThread extends Father implements Runnable {
static int count = 0;
// 公共资源
private int t = 0;
private synchronized void increase() {count++;}
@Override
public void run() {for (int x = 0; x < 100; x++) {increase();
System.out.println(Thread.currentThread().getName() + ":" + count);
// System.out.println(Thread.currentThread().getName() + ":" + t++);
}
}
}
public class MultiplyThread {public static void main(String[] args) throws InterruptedException {
// 创立多线程对象
MusicThread mt = new MusicThread() ;
Thread t1 = new Thread(mt,"abbott");
Thread t2 = new Thread(mt,"liu");
Thread t3 = new Thread(mt,"hello");
// 设置每个对象的名字
t1.start();
t2.start();
t3.start();}
}