学习笔记06-多线程

来源:互联网 发布:二维数组初始化 编辑:程序博客网 时间:2024/06/04 00:42
多线程:
进程:就是应用程序。
线程:就是进程的执行单元(一条执行路径)。
多线程:就是进程有多条执行路径。


多线程的原理:
就是CPU在各个程序之间做着高效的切换。
应用:
群聊,群视频。


并行:两个程序同时运行。(需要多核CPU)
并发:两个任务同时申请执行,但是CPU只能接受一个任务,就会安排他们轮流执行。
 但是CPU的切换速度太快了,给我们的感觉,是在同时运行。




多线程的实现方法;
1、继承Thread类。 //class MyThread extends Thread {}
步骤:
A:创建一个类(MyThread)继承Thread类。
B:重写Thread类中的run()方法,把要执行的代码写在run()方法中
C:在main函数中创建MyThread的对象。
D:启动线程。  
注意:
1、调用的是start()方法。
2、如果调用的是run(),就是一个普通的方法调用而已。


2、实现Runnable接口。//class MyRunnable implements Runnable{}
步骤:
A:创建一个类(MyRunnable)实现Runnable接口。
B:重写Runnable接口中run()方法,把要执行的代码写在run()方法中
C:在main函数中创建MyRunnable类的对象(mr)
D:将第三步创建的对象mr作为 Thread类的构造方法的参数进行传递,创建Thread类的对象。
E:启动线程。
//main函数中的代码:
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr);
t1.start();


new Thread(Runnable r);

面试题:
多线程两种实现方式的区别。
多线程执行的随机性的原理:
CPU在程序间做着高效的切换,而线程抢到CPU资源的那一刻,足够它做好多事儿了。
//就是线程在抢CPU资源,抢到资源的那一刻,足够它做好多事儿了




获取名字和设置名字:
public String getName();
public void setName(String name);


public static Thread currentThread();  //返回当前正在执行的线程对象的引用


线程的默认命名规则:
“Thread-” 加上编号。   编号是从0开始的。



另外几个常用的方法:
休眠线程:
sleep(long mills);  //让线程睡指定时间。(传的是毫秒值。 毫秒,微秒,纳秒)
//wait();
守护线程:
setDaemon(boolean flag);  //设置线程为守护线程,该线程不会单独执行,当非守护线程都执行完毕后,自动结束。


理解:
坦克大战:
老鹰:非守护线程。
玩家:守护线程。


  加入线程:
join();   //类似于插队。 让当前线程暂停,等待加入线程执行完毕后,在执行。

           礼让线程:
yield(); //让出CPU资源
举例;
5个任务在抢CPU资源,假设任务1礼让了CPU了,那么这一瞬间,这五个任务又会开始重新抢CPU资源,
可能还是任务1先抢到,所以我们看到的效果不明显。

设置线程的优先级:
setPriority();


线程的默认优先级是多少:5
线程的优先级的范围是多少: 1-10
线程的优先级越高,一定会第一个执行吗?
不一定。线程的优先级越高,只是从一定程度上来讲,能让该线程获取更多的执行权。


同步:synchronized
大白话理解:就是多线程用来解决安全问题的。
概述:
当多线程并发,有多段代码同时执行的时候,我们需要某一段代码执行期间,CPU不要做切换,就可以使用同步。


有两个方法(method,function)都加了同步,method执行期间,会去执行function?
不会。


同步代码块:
格式:
synchronized(锁对象){
//被同步的代码
}


同步方法:在方法的声明上加上synchronized。
同步代码块的锁对象是谁:任意对象。
同步方法的锁对象是谁:
静态:该类的字节码文件对象
非静态:this
注意:加锁的时候,要使用同一把锁,不然可能出现锁不住的情况。


多线程模拟卖票,为什么会出现负数和重复值的情况?
负数:
最后一次判断的时候,ticket的值是1,假如说,此时四个线程对象都进来了,那么他们打印的顺序就是:

* 开始执行
*  第一次:打印:第一张票  ,打印完了以后ticket变成0
*  第二次:打印:第0张票,打印完成后ticket的值变成-1
*  第三次:打印:第-1张票,打印完成后ticket的值变成-2
*  第四次:打印:第-2张票,打印完成后ticke的值变为-3
 


重复值:ticket--
// ticket = ticket - 1;
A:读取ticket的值。
B:修改ticket的值。
C:将修改后的值赋值给ticket。
当执行到A之后,还没有来得及执行B的时候,别的线程对象有打印操作。


这种情况产生的原因是什么? 
就是由于多线程执行的随机性和延迟性,导致结果可能会出现重复值或者负数。


多线程可能产生问题的原因:
A:是否有共享数据。
B:是否有多条语句来操作共享数据。
C:是否在多线程环境中。


0 0
原创粉丝点击