---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
多线程(概述)
进程是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序就是一个执行路径或者叫控制单元
线程就是进程中的一个独立的控制单元。线程在控制着进行的执行(一个进程中至少有一个线程)。
《Java—jvm启动的时候会有一个进程叫java.exe该进程当中至少有一个线程在负责java程序的执行,而且这个线程运行的代码存在于main方法中》该线程称之为主线程。
扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程
多线程的一个特性:随机性。谁抢到谁执行,至于执行多长时间,cpu说的算。
创建线程的第一种方式:继承Thread类。
1、定义类继承Thread。
2、复写Thread类中的run方法。目的:将自定义代码存储在run方法。让线程运行。
3、调用线程的start方法,该方法两个作用:启动线程,调用run方法。
创建线程的第二种方式:实现Runnable接口。
1、定义类实现Runnable接口
2、覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。
3、通过Thread类建立线程对象。
4、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
5、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
//需求:银行有一个金库,有2个储户分别存300元,每次存一百,存三次
//目的:该程序是否有安全问题,如果有如何解决?
class sankDemo
{
publicstatic void main(String[] args)
{
cusc = new cus();
Threadt1 = new Thread(c);
Threadt2 = new Thread(c);
t1.start();
t2.start();
}
}
class sank
{
privateint sum;
publicvoid add(int n)
{
sum= sum +n;
System.out.println("sum="+sum);
}
}
class cus implements Runnable
{
privatesank b = new sank();
publicvoid run()
{
for(intx = 0;x<3;x++)
{
b.add(100);
}
}
}
同步代码块格式:
synchronized(唯一对象)
{
需要被同步的代码;
}
同步的前提:
1、必须要有两个或者两个以上的线程。
2、必须是多个线程使用同一个锁。
同步函数的锁是this
静态同步函数的锁是Class对象
单例设计模式之懒汉式:
class Single
{
privateSingle(){}
privatestatic Single single = null;
public staticSingle getInstance()
{
if(single==null)
{//避免每次都判断锁,只有当对象为null的情况下才判断
synchronized(Single.class)
{
if(single==null)/*如果一个线程跑到第一个if后死了,另一个线程进来创建了对象释放了锁,然后那个线程醒了,进来后还要判断*/
single=new Single();
}
}
returnsingle;
}
}
wait() notify() notifyAll()都是用在同步中,因为要对持有监视器(锁)的线程操作,所以使用在同步中,因只有同步中有锁。
为什么这些操作线程的方法要定义在object类中呢?
答:因为这些方法在操作同步中的线程时,都必须要标示他们所操作线程只有的锁。
只有同一个锁上的被等待线程可以被同一个锁上的线程被notify唤醒。同时不可以对不同所中的线程进行唤醒。
也就是说等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法定义在object中。
Notify():往往唤醒线程池中的第一个,所以可能唤醒本方导致数据错乱全部等待。可以用notifyall全部唤醒。
当出现多个生产者消费者同时要做这件事情的时候要用循环while和notifyall,(通用1.while判断标记,2.把对方唤醒)当只有一个生产者和消费者时可以用if
停止线程:Stop方法已过时,如果停止线程呢:只有一种,run()方法结束
原理:开启多线程运行,运行代码通常是循环。只要控制循环,皆可以让run方法结束即线程结束。
守护线程:线程对象.setDaemon(true);将该线程标记为守护线程或用户线程。
当正在运行的线程都是守护线程时,Java虚拟机退出,程序结束。
多线程(Join方法)
特点:当A线程执行到了B线程的.join()方法时,那么A线程就会等待B线程都执行完A才会执行。它可以用于临时加入线程执行
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------