一、 多线程-------随即性(多线程的一个特性)
创建线程的第一种方式:
1、定义类继承Thread;
2、复写(方法覆盖)Thread类中的run方法;
3、调用线程的Start方法
创建线程的第二种方法:(实现Runnable接口)
1、定义类实现Runnable接口
2、覆盖Runnable接口中的run方法
将线程要运行的代码存放在该run方法中
3、通过Thread类建立线程对象;
4、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
为什么要将Runable接口的子类对象传递给Thread的构造函数
因为,自定义的run方法所属的对象是Runnable接口的子类对象,所以
要让线程去执行指定对象的run方法,就必须明确该run方法所属对象
5、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
实现方式和继承方式的区别:
实现方式的好处是避免了单继承的局限性
在定义线程时,建议使用实现方式
继承Thread,线程代码存放在Thread子类的run方法中
实现Runnalbe接口,线程代码存放在接口的子类的run方法中
多线程----单例设计模式-----饿汉式、懒汉式 (背也要背下来)
饿汉式:class Single
{
private static Single s = new Single();
private Single()
{}
public static Single getInstance()
{
return s;
}
}
饿汉式与懒汉式的区别:懒汉式的特点是实例延迟加载,在有多线程访问时存在安全问题,
可以加同步来解决,用双重判断可以解决效率低的问题
懒汉式使用的锁是 类名.class
懒汉式 class Single
{
private static Single s = null;
private Single()
{}
public static Single getInstance()
{
if (s == null)
{
synchronized(Single.class) //或synchronized(this)
{
if (s == null)
s = new Single();
}
}
return s;
}
}
二、 同步--------前提:有两个或两个以上的线程多个线程使用同一个锁
好处:解决了多线程的安全问题
弊端:多个线程需要判断锁,较为消耗资源
同步函数所用的锁是this,即为所属对象的引用
如果同步函数被静态修饰后,使用的锁就是:类名.class,即该方法所在的字节码文件对象
静态方法中不可以定义this
静态进内存时,内存没有本类对象,但一定有该类对应的字节码文件对象,即类名.class
该对象的类型是class
三、 死锁-----同步中嵌套同步
class Test implements Runnable
{
private boolean flag;
Test(boolean flag)
{
this.flag = flag;
}
public void run()
{
if (flag)
{
synchronized(MyLock.locka)
{
System.out.println("if locka");
synchronized(MyLock.lockb)
{
System.out.println("if lockb");
}
}
}
else
{
synchronized(MyLock.lockb)
{
System.out.println("else lockb");
synchronized(MyLock.locka)
{
System.out.println("else locka");
}
}
}
}
}
class MyLock
{
static Object locka = new Object();
static Object lockb = new Object();
}
class DeadLockTest
{
public static void main(String[] args)
{
Thread t1 = new Thread(new Test(True));
Thread t2 = new Thread(new Test(True));
t1.start();
t2.start();
}
}
四、 线程间通信:
多个线程操作同一个资源,但是操作的动作不同
example:E:\JAVA\MyJavaDemo\BiXiangDong\13day\thrcom
wait;
notify();
notifyAll();
都使用在同步中,因为要对持有监视器(锁)的线程操作,所以要在同步中使用,只有同步才具有锁
为什么这些操作线程的方法要定义在Object中呢????????
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程才有的锁,只有同一个锁上的被等待线程可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁,而锁可以使任意的对象,所以可以被任意对象调用的方法应该定义在Object类中
interrupt方法将冻结状态的线程强制清除,使其成为运行状态,然后改变循环标记,使线程正常运行终止。
setPriority(int); 设置线程的优先级
join();线程等待
setDaemon(boolean flag); 将线程设置为守护线程,即在后台运行
|
|