Java面试

多线程1,线程基础知识

2018-04-17  本文已影响84人  杨充211

多线程基础知识

目录介绍

0.前沿介绍

1.进程概述及多进程的意义[理解]

1.1 线程和进程

1.2 进程概述

1.3 多进程的意义

2.线程的概述和多线程的意义[理解]

2.1 什么是线程

2.2 多线程有什么意义

2.3 并行和并发

3.JVM运行原理以及JVM启动的线程探讨[理解]

3.1 Java程序运行原理

3.2 JVM的启动是多线程的吗

4.多线程程序实现的方式[掌握]

4.1 多线程程序实现的方式

第一种方式的步骤:
1: 定义一个类,让该类去继承Thread类
2: 重写run方法
3: 创建该类的对象
4: 启动线程

public class ThreadDemo {
    public static void main(String[] args) {
        // 创建对象
        MyThread t1 = new MyThread() ;
        MyThread t2 = new MyThread() ;
        // 启动线程: 需要使用start方法启动线程, 如果我们在这里调用的是run方法,那么我们只是把该方法作为普通方法进行执行
//      t1.run() ;
//      t1.run() ;
        t1.start() ;        // 告诉jvm开启一个线程调用run方法
        // t1.start() ;     // 一个线程只能被启动一次
        t2.start() ;
        
    }
}

public class MyThread extends Thread {
    @Override
    public void run() {
        for(int x = 0 ; x < 1000 ; x++) {
            System.out.println(x);
        }
    }
}
实现多线程的第二中方式步骤:
1: 定义一个类,让该类去实现Runnable接口
2: 重写run方法
3: 创建定义的类的对象
4: 创建Thread的对象吧第三步创建的对象作为参数传递进来
5: 启动线程

public static void main(String[] args) {
    // 创建定义的类的对象
    MyThread mt = new MyThread() ;
    // 创建Thread的对象吧第三步创建的对象作为参数传递进来
    Thread t1 = new Thread(mt , "张三") ;
    Thread t2 = new Thread(mt , "李四") ;
    // 启动线程
    t1.start() ;
    t2.start() ;
}

public class MyThread implements Runnable {
    @Override
    public void run() {
        for(int x = 0 ; x < 1000 ; x++) {
            System.out.println(Thread.currentThread().getName() + "---" + x);
        }
        
    }
}

4.2 多线程两种方式的区别

4.3 几个小问题探索

4.4 匿名内部类的方式实现多线程程序

5.线程调度

5.1 线程的调度问题

5.2 线程有两种调度模型

6.线程控制

6.1 线程控制之休眠线程

6.2 线程控制之加入线程

6.3 线程控制之礼让线程

6.4 线程控制之守护线程

6.5 线程控制之中断线程

7.案例分析

7.1 继承Thread类的方式卖电影票案例

public class ThreadDemo {
    public static void main(String[] args) {
        /**
         * 需求:某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。
         */
        // 创建3个线程对象
        SellTicktes t1 = new SellTicktes() ;
        SellTicktes t2 = new SellTicktes() ;
        SellTicktes t3 = new SellTicktes() ;
        // 设置名称
        t1.setName("窗口1") ;
        t2.setName("窗口2") ;
        t3.setName("窗口3") ;
        // 启动线程
        t1.start() ;
        t2.start() ;
        t3.start() ;
    }
}

public class SellTicktes extends Thread {
    private static int num = 100 ;
    @Override
    public void run() {
        /**
         * 定义总票数
         * 
         * 如果我们把票数定义成了局部变量,那么表示的意思是每一个窗口出售了各自的100张票; 而我们的需求是: 总共有100张票
         * 而这100张票要被3个窗口出售; 因此我们就不能把票数定义成局部变量,只能定义成成员变量
         */     
        // 模拟售票
        while(true) {
            if( num > 0 ) {
                System.out.println(Thread.currentThread().getName() + "正在出售" + (num--) + "张票");
            }
        }
    }
}

7.2 实现Runnable接口的方式卖电影票

public class SellTicektesDemo {
    public static void main(String[] args) {
        // 创建SellTicektes对象
        SellTicektes st = new SellTicektes() ;
        // 创建Thread对象
        Thread t1 = new Thread(st , "窗口1") ;
        Thread t2 = new Thread(st , "窗口2") ;
        Thread t3 = new Thread(st , "窗口3") ;
        // 启动线程
        t1.start() ;
        t2.start() ;
        t3.start() ;
    }
}

public class SellTicektes implements Runnable {
    private static int num = 100 ;
    @Override
    public void run() {
        while(true) {
            if(num > 0) {
                System.out.println(Thread.currentThread().getName() + "正在出售第" + (num--) + "张票");
            }
        }
    }
}

7.3 买电影票出现了同票和负数票的原因分析

public class ThreadDemo {
    public static void main(String[] args) {
        // 创建3个线程对象
        SellTicktes t1 = new SellTicktes() ;
        SellTicktes t2 = new SellTicktes() ;
        SellTicktes t3 = new SellTicktes() ;
        // 设置名称
        t1.setName("窗口1") ;
        t2.setName("窗口2") ;
        t3.setName("窗口3") ;
        // 启动线程
        t1.start() ;
        t2.start() ;
        t3.start() ;
    }
}

public class SellTicktes extends Thread {
    private static int num = 100 ;
    @Override
    public void run() {
        // 模拟售票
        while(true) {
            if( num > 0 ) {
                try {
                    Thread.sleep(100) ;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "正在出售" + (num--) + "张票");
            }
        }
    }
}

7.4 线程安全问题的产生原因分析


7.5 同步代码块的方式解决线程安全问题

synchronized(对象){
            需要同步的代码;
        }
上一篇 下一篇

猜你喜欢

热点阅读