多线程!!

多线程

进程:每个进程都有独立的代码和数据空间,进程是资源分配的最小单位,每个独立的程序占有一个进程
线程:表示程序的执行流程,是CPU调度执行的基本单位,同一类线程共享代码和数据空间进程是线程的容器,即一个进程包含1+n个线程
进程内含有多个线程
在计算机中所有程序都通过CPU来执行,也就是在某个时间点上,CPU上只能运行一个程序,只是CPU运行速度非常快,在不同的程序(进程)间切换所花费的时间特别短,用户才感觉好像多个进程同时在运行
多线程:每一个线程完成一个功能,并与其他线程在同一个进程中并发执行
并发:同事执行多个操作的思想,在Java中被称为并发,将并发完成的每一件事称为线程
线程的优点:

线程的创建:

创建Thread的子类继承Thread--------重写run();方法

使用该方法创建的两个对象不相同因为使用new都算开辟了同一块空间(t1!=t2)
// MyThread my2 = new MyThread();
// //调用方法设置名称
// my1.setName(“林青霞”);
// my2.setName(“刘意”);
// my1.start();
// my2.start();
//带参构造方法给线程起名字
// MyThread my1 = new MyThread(“林青霞”);
// MyThread my2 = new MyThread(“刘意”);
// my1.start();
// my2.start();
当继承Thread类时可用自己的无参构造方法再用setName()为线程起名或者使用super()继承父类有参的构造方法
直接起名
在Thread子类中重写的方法
直接调用run();方法和使用start();方法调用有一定区别
start();方法(开启子线程)在main方法中(main相当于主线程)-----对于其他线程当前线程叫主线程
直接调用run();方法则不会交替进行—谁先调用谁进行。
主线程中子线程是交替运行的

使用该方法创建的两个Thread的对象相同,因为使用的是同一个Runnable接口(t1=t2)
// 创建Thread类的对象,并把C步骤的对象作为构造参数传递
// Thread(Runnable target)
// Thread t1 = new Thread(my);
// Thread t2 = new Thread(my);
// t1.setName(“林青霞”);
// t2.setName(“刘意”);
// Thread(Runnable target, String name)
Thread t1 = new Thread(my, “林青霞”);
Thread t2 = new Thread(my, “刘意”);
Thread的两个构造方法------使用setName()为线程起名或使用第二个构造方法直接起名
在Runnable接口实现类中重写的run();方法
直接调用run();以此对象作为参数构造Thread类调用start();方法使用start();方法调用有一定区别:
start();方法(开启子线程)在main方法中(main相当于主线程)-----对于其他线程当前线程叫主线程
直接掉用run();方法则不会交替进行—谁先调用谁进行。
主线程中子线程是交替运行的
两种方式的对比:
使用继承自Thread类的方式创建多线程:
优点:编写简单、如果需要访问当前线程、直接使用this即可
this的使用
继承父类的两个方法
setName(" ");----为线程起名
getName();----获取该线程名称
使用this关键字代表当前 在当前线中使用当前线程(this.方法)代表当前线程
----this.setName();–在当前类中为线程赋名时使用 在主线程中使用子线程(对象名.方法)
----this.getName();–在当前类获取线程名时使用
获创建Thread对象时使用(对象名.方法名)
缺点:继承自Thread类、不能再继承其他类
使用实现Runnable接口的方式创建多线程:
优点:可以继承其他类
缺点:编写稍微复杂、访问当前线程、需要Thread.currentThread();方法
Thread.currentThread();的使用----和this相似在当前线中使用当前线程(Thread.currentThread().方法)代表当前线程
使用Thread.currentThread();代表当前在主线程中使用子线程(对象名.方法)
----Thread.currentThread().setName();–在当前类中为线程赋名时使用
----Thread.currentThread().getName();–在当前类获取线程名时使用
获创建Thread对象时使用(对象名.方法名)注意这个对象时Thread

进程中多个线程启动时(运行–堵塞)
当进程结束—死亡

进程中至少有一个线程,在众多线程中,有时需要优先执行一个线程,这个线程的优先级越高,得到CPU执行的机会就越大,反之就越小。
主线程(当前线程中)主线程在第一位时不论优先级、总是先执行
线程的优先级使用1–10之间的整数来表示,数值越大,优先级越高,除了通过整数表示优先级,还可以通过Thread类的3个静态常量来表示:MAX_PRIORITY(值=10)、NORM_PRIORITY(值=5)、MIN_PRIORITY(值=1)
设置优先级,只是增加CPU调度的机会,往往还需要直接设置线程中断,让CPU执行其他线程
可以使用静态方法sleep()方法来使正在执行的线程以指定的毫秒数,进入睡眠状态,在该休眠时间内,CPU会调度其他线程。
为了更好的操作线程,Thread类还提供了yield方法,来暂停当前正在执行的线程对象,把机会让给相同或者优先级更高的线程,因此,yield()方法也称为线程让步。
在多线程操作时,有时候还需要让某个线程插队,Thread类中题提供了join()方法,来实现这一步功能。当线程调用join()方法时,线程会进入阻塞状态,直到join()方法加入的线程执行完毕,该线程才会继续执行。
{
.isAlive();判断线程是否存活(返回boolean类型)
setPriority(int);设置优先级 都可以在当前线程中使用或主线程中创建对象使用
getPriority();返回线程的优先级(int 类型)
join();线程的插队-----设置当前线程(主线程)被其他线程插队
}
Thread.sleep(int);线程的休眠—(Thread的静态方法)—设置当前线程休眠时间
Thread.yield();线程让步----(Thread的静态方法)----设置当前线程让步
线程的同步:
在多线程中,为了处理共享资源竞争,java可以使用同步机制;所谓同步机制,指的是两个线程同时作用在一个对象上,应该保持对象数据的统一性和整体性。(一个一个进行不会出现两个抢占一个的问题)
Java提供了关键字synchronized,可以处理多线程同步竞争资源问题。
synchronized可用于修饰方法,也可用于代码段

public synchronized void refound(){
//退票bj2zz++;}

二public static final Object lock=new Object();
synchronized(lock){ 代码 }
在要调用的资源中创建一个锁
//这种方式是谁使用资源谁来加锁----太繁琐----线程多时容易出错
//加锁之后—资源锁定—保证资源的完整性–防止多个线程对一个变量操作时存在竞争
每一个线程使用该资源都需要加锁
线程的死锁

为防止该现象发生–需要设置一个先后顺序

2.保证锁的顺序一致
public void sale(){
synchronized (lock) {
bj2zz–;
synchronized (lock2) {
bj2zz2–;
}
}
//售票
//注意嵌套锁的顺序----谁先售票谁就先退票—否则会出现线程的死锁
lock售票占用bj2zz资源lock2退票占用bj2zz2
其后的lock2售票和lock退票都为执行完无法结束占用—死锁现象形成
}
public void refound(){
synchronized (lock2) {
bj2zz2++;
synchronized (lock) {
bj2zz++;
}
}
}

在售票问题中多个窗口出售票和售票退票的不同
售票退票存在资源抢占的问题—用锁可解决

售票问题–定义一个全局的变量–不能定义类部变量或局部变量否则通过同一个类调用多个线程时将会定义一个新的变量----就就会变成自己出售自己的票
使用sheep()方法—出现的问题----使用线程同步解决–加锁
通过加入延迟后,就产生了连个问题:

  • A:相同的票卖了多次
  •  CPU的一次操作必须是原子性的
    
  • B:出现了负数票
  •  随机性和延迟导致的
    

同步的特点:

  •  前提:
    
  •  	多个线程
    
  •  解决问题的时候要注意:
    
  •  	多个线程使用的是同一个锁对象
    
  • 同步的好处
  •  同步的出现解决了多线程的安全问题。
    
  • 同步的弊端
  •  当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。
    

*/
// 线程安全的类
StringBuffer sb = new StringBuffer();
StringBuilder SB1=new StringBuilder();
Vector v = new Vector();
Hashtable<String, String> h = new Hashtable<String, String>();

	// Vector是线程安全的时候才去考虑使用的,但是我还说过即使要安全,我也不用你
	// 那么到底用谁呢?
	// public static <T> List<T> synchronizedList(List<T> list)
	List<String> list1 = new ArrayList<String>();// 线程不安全
	List<String> list2 = Collections
			.synchronizedList(new ArrayList<String>()); // 线程安全
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值