多线程基础
一、创建新执行线程有两种方法继承Thread、实现Runnable接口
方法一:继承Thread类
1 定义一个类继承Thread。
2 重写run方法。
3 创建子类对象,就是创建线程对象。
4 调用start方法,开启线程并让线程执行,同时还会告诉jvm去调用run方法。(线程对象调用start开启线程,并让jvm调用run方法在开启的线程中执行。)
public class MyThread extends Thread{
public MyThread(String name) {
super(name);
// TODO Auto-generated constructor stub
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0 ;i<= 1000;i++) {
System.out.println(getName()+"正在运行新线程!!!!!");
}
}
}
/**
* 线程对象调用run方法不开启线程,仅是对象调用方法。线程对象调用start开启线程,并让jvm调用run方法在开启的线程中执行。
* @author 焦大宝
*
* 多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈。
*
*/
public claspublic class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread("第一个线程");
myThread.start();
}
}
方法二:实现Runnable接口
Runnable接口用来指定每个线程要执行的任务。包含了一个 run 的无参数抽象方法,需要由接口实现类重写该方法。
创建线程的步骤。
1、定义类实现Runnable接口。
2、覆盖接口中的run方法。。
3、创建Thread类的对象
4、将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
5、调用Thread类的start方法开启线程。
public class MyRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0 ;i <= 1000;i++) {
System.out.println("这是我的第一个Runnable线程!");
}
}
}
public class Teat {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
for(int i = 0 ;i<= 1000;i++) {
System.out.println("主线程main正在运行新线程!!!!!");
}
}
方法三:匿名内部类创建线程
//方法1
new Thread() {
public void run() {
for (int x = 0; x < 40; x++) {
System.out.println(Thread.currentThread().getName()
+ "...X...." + x);
}
}
}.start();
//方法2
Runnable r = new Runnable() {
public void run() {
for (int x = 0; x < 40; x++) {
System.out.println(Thread.currentThread().getName()
+ "...Y...." + x);
}
}
};
new Thread(r).start();
二、线程安全
1.引起线程安全的原因:线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全
2.解决线程安全的三种方案:
2.1 同步代码块
使用方法:
* Object lock = new Object();
* synchronized (锁对象 lock) {
* //可能出现线程安全的代码
* }
2.2同步方法
使用方法:
//同步方法,在方法声明上加上synchronized,同步方法中的锁对象是 this
public synchronized void run() {
//可能会产生线程安全问题的代码
}
//静态同步方法: 静态同步方法中的锁对象是 类名.class
public static synchronized void method(){
//可能会产生线程安全问题的代码
}
2.3Lock接口
Lock接口中的常用方法 :lock 获取锁 unlock释放锁
使用方法:
//创建Lock锁对象
Lock ck = new ReentrantLock();
ck.lock();
//可能会产生线程安全问题的代码
ck.unlock();