黑马程序员_多线程

来源:互联网 发布:qq音乐数据库 api接口 编辑:程序博客网 时间:2024/06/05 02:24
/*
什么是进程:
  正在运行的程序所占有的内存的空间,叫做进程。
  内存360safe.exe,占有内存的空间,进程。木马,修复,体检,是整个360safe进程中的一个子程序
什么是线程:
  一个应用程序中的子程序,对于CPU,子程序可以有一条独立的执行路径,称为线程。
  特点:依靠一个应用程序,对于其他子程序,独立被CPU执行的
多线程技术好处
   充分利用CPU的资源,程序的同时运行,提高效率
Java程序中的线程创建
  利用操作系统,我们不能直接在系统上创建并运行线程,必须依靠JVM,帮助我们完成这个功能。万物都是对象,线程这个事物也是对象,java.lang.Thread
  创建线程的第一种方法
定义类继承Thread  class extends Thread
重写Thread类的run方法   public void run
创建Thread类的子类对象
调用子类对象中的start()方法,开启线程
start()做了两件事,告诉JVM开启一个对CPU的执行路径,调用run方法


获取和设置线程的名字
   既然获取线程的名字,找描述线程对象的类Thread,提供获取名子的方法
   Thread类的方法 String getName()获取线程的名字
   获取到运行main方法的线程的名字,main方法运行也是由线程来执行的,如果我们可以获取到执行main方法的线程对象 Thread类中,静态方法:
   static Thread currentThread()返回当前正在执行的线程对象,适合于不是Thread子类中获取线程名字
   Thread类的方法  void setName(字符串的名字)设置线程名字
   利用Thread类的构造方法,传递字符串的名字  Thread(字符串名字)
多线程操作同一个数据,有安全隐患,必须考虑安全问题
  解决线程操作同一个数据的安全问题,如果一个线程休眠了,其他线程不能执行,同一个时间内,操作数据的线程,只能有一个,保证数据的安全了
引出创建线程的第二种方式
定义类,实现Runnable接口
重写run方法
创建Thread类对象 new Thread()构造方法中,传递Runnable接口的实现类对象
调用Thread对象方法start(),开启线程
  两种创建方式的区别:第一种继承,单继承局限性,数据是线程的独有数据
   第二种创建方式,实现接口方式,避免了单继承的局限性,同时线程的数据共享
同步机制,保证多线程在操作共享数据的安全性
    同步代码块:
        格式:  synchronized(对象){
              线程操作的共享数据
         }
 对象:专业名词,对象监视器,锁
 同步代码块,作用分配锁,线程进入同步代码块后,会把锁给线程,持有锁的线程,当线程执行完毕后,出去同步代码块,锁还给同步代码块,一但线程持有了锁,肯定进入了同步代码块,没有锁的线程进不来
但是加上同步以后,程序的运行速度,有所减慢,线程安全了,执行效率降低了,在安全和效率的问题上,只能选择牺牲效率了


模拟银行的存钱
*/
class Bank{
private static int sum = 0 ;
public static synchronized void add(int money){
// Bank.class返回的是 Bank类的class文件对象
sum = sum + money;
System.out.println("sum="+sum);
}
}
//定义储户,多线程并发存钱
class Cust implements Runnable{
private Bank b = new Bank();
public void run(){
for(int x = 0 ; x < 3 ; x++)
b.add(100);
}
}
public class ThreadDemo3 {
public static void main(String[] args) {
Cust c = new Cust();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();

}
}
//多线程并发的单例模式懒汉
class Single {
private Single() {
}


private static Single s = null;


public static Single getInstance() {
if (s == null) {
synchronized (Single.class) {
if (s == null)
s = new Single();
}
}
return s;
}
}
class SingleTest implements Runnable {
public void run() {
for (int x = 0; x < 30; x++) {
Single s = Single.getInstance();
System.out.println(s);
}
}
}


public class ThreadDemo4 {
public static void main(String[] args) {
SingleTest s = new SingleTest();
new Thread(s).start();
new Thread(s).start();
new Thread(s).start();
new Thread(s).start();
}
}


// 死锁的案例
 


class Dead implements Runnable{
private boolean flag;
Dead(boolean flag){this.flag = flag;}
public void run(){
while(true){
//如果flag = true线程进入A同步代码块,进B同步代码块
if(flag){
synchronized(LockA.locka){
System.out.println("if..locka");
//进B同步代码块
synchronized(LockB.lockb){
System.out.println("if..lockb");
}
}
}else{
//如果flag = false 线程进入B同步代码块,进入A同步代码块
synchronized(LockB.lockb){
System.out.println("else..lockb");
//进A同步代码块
synchronized(LockA.locka){
System.out.println("else..locka");
}
}
}
}
}
}


public class ThreadDemo5 {
public static void main(String[] args) {
Dead d1 = new Dead(true);//线程进入A代码块
Dead d2 = new Dead(false);//线程进入B代码块
Thread t1 = new Thread(d1);
Thread t2 = new Thread(d2);
t1.start();
t2.start();
}
}
//定义两个锁,A锁,B锁,唯一对象
class LockA{
public static final LockA locka = new LockA();
}
class LockB{
public static final LockB lockb = new LockB();
}
0 0