------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
进程:是一个正在执行中的程序。每一个进程执行都有一个执行的顺序,该顺序是一个执行路径,或者叫一个控制单元。
线程:是进程中用于控制程序执行的控制单元。
关系:一个进程中至少有一个线程。
多线程:是指很多线程在cpu中快速切换,由于切换时间很快,在我们的肉眼感知几乎无法察觉。多个线程争夺cpu的执行权,具备随机性。
创建线程的方式:
第一种:继承Thread类。因为需要覆盖run方法。
步骤:
1. 继承Thread类。
2. 覆盖run方法,将需要运行的代码放入其中。
3. 创建Thread类的子类对象,其实就是在创建线程,用start方法调用。
class Bank extends Thread
{
public void run()//共享数据
{
for(int i=0;i<100;i++)
{
System.out.println(this.getName()+"-----"+i);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
Bank b1 = new Bank();//Thread的子类继承线程的特性
Bank b2 = new Bank();
b1.start();
b2.start();
}
}
第二种:实现Runnable接口。
步骤:
1,定义了实现Runnable接口。
2,覆盖接口的run方法。将多线程要运行的代码存入其中。
3,创建Thread类的对象(创建线程),并将Runnable接口的子类对象作为参数传递给Thread的构造函数。
为什么要传递?因为线程要运行的代码都在Runnable子类的run方法中存储。所以要将该run方法所属的对象
传递给Thread。让Thread线程去使用该对象调用其run方法。
4,调用Thread对象的start方法。开启线程。
class MyThreadDemo implements Runnable
{
public void run() {
for(int i=0;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}
public class RunnableDemo {
public static void main(String[] args) {
MyThreadDemo m = new MyThreadDemo();
Thread t1 = new Thread(m);
Thread t2 = new Thread(m);
t1.start();
t2.start();
}
}
多线程运行的安全问题
异常产生原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致了共享数据的错误。
解决方案:对多条操作共享数据的语句,只能让一个线程都执行完再执行过程中其他线程不可以参与执行。java对于多线程的安全问题提供了专业的解决方式,同步代码块。
格式
synchronized(对象){需要被同步的代码}
如Object Obj=new Object()
synchronized(Obj)---同步锁
<span style="font-family: Arial; ">同步的前提</span>
1.必须要有两个或两个以上的线程。
2.必须是多个线程使用同一个锁。
3.必须保证同步中只有一个线程在执行。
同步的好处:解决了多线程的安全问题。
同步的弊端:多次重复判断同步锁,消耗了资源。
如何找问题
1.明确哪些是多线程运行代码
2.明确共享数据
3.明确多线程运行代码中哪些语句是操作共享数据
同步的两种表现方式
同步代码块:synchronized(对象){}
同步函数:用synchronized修饰函数
同步函数用的是哪个锁
函数需要被对象调用,那么函数都有一个所属对象引用。就是this。
所以同步函数使用的锁就是this
如果同步函数被修饰后使用的锁不再是this了因为经静态方法中不可以定义this。
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件。
静态的同步方法使用的锁是该方法所在对象的字节码文件对象---类名.class 该对象的类型是class
class MyThreadDemo implements Runnable
{
public void run()
{
synchronized(this)//使用对象锁
{
print();
}
}
public void print()
{
for(int i=0;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}
public class RunnableDemo {
public static void main(String[] args) {
MyThreadDemo m = new MyThreadDemo();
Thread t1 = new Thread(m);
Thread t2 = new Thread(m);
t1.start();
t2.start();
}
}