多线程:
概述:进程有多条执行路径。
进程:可执行程序(文件),一般是.exe文件。
线程:进程的执行路径(单元)。
Thread 类中的方法:
start(); //开启线程
currentThread(); //获取当前正在执行的线程对象。
getName(); //获取线程的名字。
sleep(long times); //让线程睡指定时间, 单位是毫秒。
理解的单位换算:
1秒 = 1000毫秒
1毫秒 = 1000微秒
1微秒 = 1000纳秒
1纳秒 = 1000皮秒
//ConcurrentModificationException 并发修改异常的单词
实现方式:
第一种: 实现 Runnable 接口。
A:搞一个类MyRunnable(资源类)去实现Runnable接口。
B: 重写run()方法,讲要执行的代码写在run()中。
C:创建资源类对象。
D:创建线程对象,构造方法中放的是资源类对象。
MyRunnable mr = new MyRunnable();
Thread th = new Thread(mr);
new Thread(new Runnable(){
//重写父接口的抽象方法
});
E:开启线程。
注意:开启线程调用的是 start()方法。
线程不能重复开启,否则会报“线程状态非法异常”。 IllegalStateException
第二种实现方式: 继承 Thread 类。
A:搞一个类MyThread去继承Thread类。
B:重写Thread类中的run()方法,将要执行的代码写在run()中。
C:创建线程对象。
//注意:这里创建的是MyThread类的对象。
MyThread mt = new MyThread();
new Thread() {
//重写父类的抽象方法
};
D:开启线程。
第三种:实现 Callable 接口。 call();
注意:该方式只适用于 线程池。
线程安全问题:(线程同步)
什么时候会用到同步?
多线程 并发 操作同一数据,有可能引发安全问题,就需要用同步来解决。
多线程模拟买票出现负数和重复值:
负数:
关键点: tickets=1的时候,三个线程对象都进入到if()语句中了。
当tickets的值=1的时候,此时线程1先抢到资源,判断tickets>0成立,所以线程1进来,
线程1还没来记得继续往下执行的时候,线程2抢到了资源,线程2判断tickets>0成立,所以线程2进来,
同理,线程2还没来记得继续往下执行的时候,线程3抢到了资源,线程3判断tickets>0成立,所以线程3进来
此时,三个线程对象都已经进入到了if语句的里边:
假设线程1先打印: tickets = 1, 完事儿后会将 tickets的值改为 0
线程2打印的时候: tickets = 0,完事儿后会将 tickets的值改为 -1
线程3打印的时候: tickets = -1,完事儿后会将 tickets的值改为 -2
重复值:
关键点:tickets-- //tickets = tickets - 1;
tickets--做了三件事情:
1、读取tickets的值。
2、修改tickets的值。
3、将修改后的值重新赋值给tickets。
当还没来得及重新赋值的时候,如果别的线程对象抢到了资源,打印的就是重复值。
同步代码块:
synchronized(任意对象){
//可能出问题的代码
}
JDK1.5的新特性:
A:互斥锁。 Lock lock = new ReentrantLock();
lock.lock();
//可能出问题的代码
lock.unLock();
B:Java内置有线程池。
C:线程池中可以提交 Callable 接口的子类对象。
|
|