什么进程:正在执行的程序
什么是线程Thread:线程是进程的基本单位,一个进程中可以同时存在多个线程。
实现线程有两种方式:
- 继承Thread类
- 实现Runnable接口
继承Thread类
1 2
| .start() 是开启多线程,并执行run()里面的代码,主程序还会继续执行后面的代码 .run() 是执行一个方法
|
例子:
Task1.java - 线程1
1 2 3 4 5 6 7 8 9 10 11
| public class Task1 extends Thread{
@Override public void run() { for (int i = 1; i <= 100; ++i) { System.out.println("i = " + i); } } }
|
Task2.java - 线程2
1 2 3 4 5 6 7 8 9 10 11
| public class Task2 extends Thread { @Override public void run() { for (int j = 1; j <= 100; ++j) { System.out.println("j = " + j); } } }
|
Window.java - 主线程
1 2 3 4 5 6 7 8 9 10 11
| public class Window { public static void main(String[] args) { Task1 t1 = new Task1(); Task2 t2 = new Task2(); t1.start(); t2.start(); } }
|
静态方法:
1 2 3 4 5 6 7 8 9 10 11 12
| 1. Thread.yield() 时间礼让,可以在线程中写该方法,当执行到该方法时,会将CPU给其他线程 例如: @Override public void run() { for (int i = 1; i <=10; ++i) { System.out.println(i); Thread.yield(); } }
2. Thread.sleep() 睡眠,单位是毫秒
|
实现Runnable接口
Task1.java - 线程1
1 2 3 4 5 6 7 8 9 10 11
| public class Task1 implements Runnable {
@Override public void run() { for (int i = 1; i <= 10; ++i) { System.out.println("i = " + i); } } }
|
Task2.java - 线程2
1 2 3 4 5 6 7 8 9 10 11
| public class Task2 implements Runnable { @Override public void run() { for (int j = 1; j <= 10; ++j) { System.out.println("j = " + j); } } }
|
Window.java - 主程序
1 2 3 4 5 6 7 8 9 10 11 12
| public class Window { public static void main(String[] args) { Runnable task1 = new Task1(); Runnable task2 = new Task2(); Thread t1 = new Thread(task1); Thread t2 = new Thread(task2); t1.start(); t2.start(); } }
|
最好实现Runnable,因为类是单继承的,减少继承的使用
线程安全问题
线程安全问题:当多个线程操作同一个共享数据时,引发的一种不正常的结果
如何解决:给公共代码块加上锁,通过sychronized
TicketSystem.java - 线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class TicketSystem implements Runnable { public static int ticketNum = 20;
@Override public void run() { for (int i = 1; i <= 30; ++i) { synchronized (TicketSystem.class) { if (ticketNum >= 1) { --ticketNum; System.out.println("购票成功,剩余" + ticketNum); } } } } }
|
Window.java - 主线程
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Window { public static void main(String[] args) { TicketSystem ts = new TicketSystem(); Thread t1 = new Thread(ts); Thread t2 = new Thread(ts); Thread t3 = new Thread(ts); t1.start(); t2.start(); t3.start(); } }
|
总结
实现线程有什么方式:
- 继承Thread类
- 实现Runnable接口
如何启动线程?直接执行run()和start()的区别?
.start()方法启动线程,run()只是执行普通的方法
什么情况下会发生线程安全问题:
当多个线程操作同一个共享数据时
如何解决安全问题:
同步加锁