本帖最后由 小石姐姐 于 2018-4-26 14:16 编辑
Java多线程笔记
Day_11多线程多线程是怎么实现的,线程是什么:
进程:当前正在运行的程序,一个应用程序在内存中的执行区域
线程:线程依赖于进程,他是进程中的执行控制单元,执行路进程就是一个应用程序 同步:指的是单线程,一步一步的执行,一个执行完再执行下一个 异步:指的是多线程,同时进行 阻塞:指的是上一步成还没有执行完,程序就停留在这里 CPU在执行程序的随机性,所以多个线程同时运行,不一定哪一个线程在前 多线程两种实现的方式: 线程安全问题: 多线程卖火车票练习: 假如一个线程执行static void sleep( )方法,就是让线程先睡一会, 假如不使用synchronized来给多线程上锁,则就会发生负数票数,异常
/*
* 12306卖火车票
*
*/
public class MyThreadTest {
public static void main(String[] args) {
// 创建Ticket
// Ticket tick = new Ticket();
Ticket2 tick = new Ticket2();
// 创建多线程对象
Thread t1 = new Thread(tick);
Thread t2 = new Thread(tick);
Thread t3 = new Thread(tick);
// 修改线程名称
t1.setName("一号窗口");
t2.setName("二号窗口");
t3.setName("三号窗口");
// 打开线程
t1.start();
t2.start();
t3.start();
}
}
class Ticket implements Runnable {
// 定义共享资源
private Integer number = 100;
@Override
public synchronized void run() {
while (true) {
// 当票数大于零就继续卖票
if (number > 0) {
try {
Thread.sleep(60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
System.out.println("----------");
}
System.out.println(Thread.currentThread().getName() + "火车票剩余量:" + number);
number--;
} else {
return;
}
}
}
}
//
class Ticket2 implements Runnable {
// 定义共享资源
private Integer number = 100;
@Override
public void run() {
while (true) {
// 当票数大于零就继续卖票
method();
}
}
//这里我们抽取方法的时候
private synchronized void method() {
if (number > 0) {
try {
Thread.sleep(60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
System.out.println("----------");
}
System.out.println(Thread.currentThread().getName() + "卖掉了第" + number+"张票");
number--;
} else {
// System.out.println("票卖完了");
return;
}
}
}同步代码块即使用关键字synchronized修饰的方法,一旦被一个线程访问,则整个方法全部锁住,其他线程则无法访问 synchonized
注意:
静态方法的锁对象是当前类的字节码 非静态方法的锁对象是this
在run方法中抽取的方法,并且被synchronized修饰,或者方法体内被 synchronized(锁){ 需要加锁的代码块 }
private synchronized void printMehtod(int count, HashSet<Integer> array) {
// 金额总和
int sum = 0;
System.out.print("在此次抽奖过程中," + Thread.currentThread().getName() + "总共产生了" + count + "个奖项,分别为:");
for (Integer integer : array) {
sum += integer;
System.out.print(integer + ",");
}
System.out.println("最高奖项为" + Collections.max(array) + "元,总计额为" + sum + "元");
//产生出最大奖项
for (Integer integer : array) {
if (integer==800) {
System.out.println(Thread.currentThread().getName()+"产生最大奖,最大奖为:"+integer);
}
}
}Synchronized的应用场景 在使用线程时,我们先要控制CPU的随机分配.,那我们将Run方法中的操作进行上锁,当一个线程执行完毕以后,后一个线程才会执行 这里我们要分清楚,线程共同的元素和非共有的元素 创建线程有两种方式 第一种方式: 第二种方式: 自己创建一个实现Runnable接口的类 * 格式: 类名 对象名= new 类名(); 使用线程就创建几个Thread对象 Thread t1=new Thread(对象名) Thread t1=new Thread(对象名) Runnable接口出现的原因 因为Java只支持单继承, 如果继承了Thread类, 就无法继承其他类, 局限性太大, 所以使用实现Runnable接口的方式, 既能继承其他类, 还能实现多个接口, 不会影响类的扩展性
多线程实现方式2: 实现Runnable接口, 重写run()方法 步骤
|