基本概念
程序(programm):是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码。
进程(process):程序的一次执行过程,或是正在运行的一个程序。
进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域。
线程(thread):进程可进一步细化为线程,是一个程序内部的一条执行路径。
线程作为调度和执行的单位,每个线程拥独立的运行栈和程序计数器(pc),线程切换的开销小。
并行:多个CPU同时执行多个任务。
并发:一个CPU(采用时间片)同时执行多个任务。
1、继承Thread类的方式
步骤:
1. 创建一个继承于Thread类的子类
2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中
3. 创建Thread类的子类的对象
4. 通过此对象调用start():①启动当前线程 ② 调用当前线程的run()
(以火车站买票为例)
同步代码块
synchronized(同步监视器){
需要同步的代码
}
说明:
1、操作共享数据的代码,即为需要被同步的代码。
2、共享数据:多个线程共同操作的变量。比如此例子中的stack就是共享数据。
3、同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。
要求:多个线程共同用一个同步监视器,即同用一把锁。
public class WindowTest1 {
public static void main(String[] args) {
Window1 w1 = new Window1();
Window1 w2 = new Window1();
Window1 w3 = new Window1();
w1.setName("线程一");
w2.setName("线程二");
w3.setName("线程三");
w1.start();
w2.start();
w3.start();
}
}
class Window1 extends Thread{
private static int tick = 100;
@Override
public void run() {
while (true){
synchronized (this){//解决线程安全问题
if(tick > 0){
System.out.println(Thread.currentThread().getName()+"有余票,票号:"+tick--);
}else
break;
}
}
}
}
同步方法
public class WindowTest3 {
public static void main(String[] args) {
Window3 w1 = new Window3();
Window3 w2 = new Window3();
Window3 w3 = new Window3();
w1.setName("线程一");
w2.setName("线程二");
w3.setName("线程三");
w1.start();
w2.start();
w3.start();
}
}
class Window3 extends Thread{
private static int ticked = 100;
@Override
public void run() {
while(true){
synchronized (this) {
show();
if (ticked <= 0)
break;
}
}
}
private static synchronized void show(){
if (ticked > 0){
System.out.println(Thread.currentThread().getName()+"有余票,票号:"+ticked--);
}
}
}
执行结果
实现Runnable接口的方式
步骤:
1. 创建一个实现了Runnable接口的类
2. 实现类去实现Runnable中的抽象方法:run()
3. 创建实现类的对象
4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
5. 通过Thread类的对象调用start()
public class WindowTest {
public static void main(String[] args) {
Window w = new Window();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口一:");
t2.setName("窗口二:");
t3.setName("窗口三:");
t1.start();
t2.start();
t3.start();
}
}
class Window implements Runnable{
public int stack = 100;//因为接口只有一个所以不需要用静态
@Override
public void run() {
while(true){
synchronized (this){
if(stack > 0){
System.out.println(Thread.currentThread().getName()+"有余票,票号:"+stack--);
}else {
break;
}
}
}
}
}
执行结果同上