多线程---中,创建方法,终端,属性,线程安全(重点),

1.创建线程的方法

  • 1.继承自Thread,重写run方法,
  • 2.实现runnable接口,把runnable接口的实例赋值给Thread
import java.util.TreeMap;

/**
 * User:yang
 */
class MyTask implements Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("hello");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ThreadDemo2 {
    public static void main(String[] args) {
        Runnable myTask=new MyTask();
        Thread t=new Thread(myTask);
        t.start();
    }
}

  • 3.匿名内部类(thread)
Thread t2=new Thread(){
            @Override
            public void run() {
                long b=0;
                for (long i = 0; i <count ; i++) {
                    b++;
                }
            }
        };
  • 4.匿名内部类(runnable)
    public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        });
        t.start();
    }
  • 5.使用lambda表达式创建线程
   public static void main(String[] args) {
        Thread t=new Thread(()->{
            System.out.println("hello");
        });
        t.start();
    }

2.线程属性

  • 线程设置名称setName()
/**
 * User:yang
 */
public class ThreadDemo3 {
    public static void main(String[] args) {
        Thread t1=new Thread(){
            @Override
            public void run() {
                while (true){
                    System.out.println("hello");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t1.setName("t1");
        t1.start();

        Thread t2=new Thread(){
            @Override
            public void run() {
                while (true){
                    System.out.println("hello");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t2.setName("t2");
        t2.start();
    }
}

  • 打印各种属性
/**
 * User:yang
 */
public class ThreadDemo4 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            Thread.currentThread().setName("1111");
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "正在运行中");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + "运行完毕,即将销毁");

        });
        System.out.println(t.getId());
        System.out.println(t.getName());
        System.out.println(t.getState());
        System.out.println(t.isDaemon());
        System.out.println(t.getPriority());
        System.out.println(t.isAlive());
        System.out.println(t.isInterrupted());
        t.start();
        System.out.println("线程创建之后");System.out.println(t.getId());
        System.out.println(t.getName());
        System.out.println(t.getState());
        System.out.println(t.isDaemon());
        System.out.println(t.getPriority());
        System.out.println(t.isAlive());
        System.out.println(t.isInterrupted());
    }
}

3.Start方法

  • 线程对象被创建出来并不意味着线程就开始运行了,需要Start

4.中断一个线程

  • 1.通过共享的标记
/**
 * User:yang
 */
public class ThreadDemo6 {
    static boolean isRunning = true;

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread() {
            @Override
            public void run() {
                while (isRunning) {
                    System.out.println("hello");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t.start();
        Thread.sleep(5 * 1000);
        isRunning = false;
    }

}

  • 2.调用 interrupt()方法
/**
 * User:yang
 */
//调用 interrupt()方法终止
public class ThreadDemo7 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(){
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()){
                    System.out.println("hello");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                }
            }
        };
        t.start();
        Thread.sleep(5*1000);
        System.out.println("线程终止");
        t.interrupt();
    }
}

5.等待线程机制

  • 不是有顺序的开始,而是能确认结束的顺序。
  • join 方法
/**
 * User:yang
 */
public class ThreadDemo8 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(){
            @Override
            public void run() {
                int i=0;
                while (i<5){
                    System.out.println("jelol");
                    i++;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };t.start();
        //执行到join就会阻塞等待,等到t执行完毕,join才会往下执行
        Thread.sleep(6000);
        System.out.println("即将调用join");
        t.join();
        System.out.println("t执行完毕");
    }
}

6. 获取当前线程引用

/**
 * User:yang
 */
public class ThreadDemo9 {
    public static void main(String[] args) {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getId());
                System.out.println(this.getId());
            }
        };
        t1.start();
        Thread t2 = new Thread() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getId());
                System.out.println(this.getId());
            }
        };
        t2.start();

        System.out.println(Thread.currentThread().getId());

    }
}

7. 线程休眠

8.线程的状态

  • NEW

  • RUNNABLE

  • BLOCKED

  • WAITING

  • TIMED_WAITING

  • TERMINATED

/**
 * User:yang
 */
public class ThreadDemo10 {
    public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <1000_0000 ; i++) {

                }
            }
        });
        System.out.println("before"+t.getState());
        t.start();
        while (t.isAlive()){
            System.out.println("during"+t.getState());

        }
        System.out.println("end"+t.getState());

    }
}

/**
 * User:yang
 */
public class ThreadDemo11 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
               while (true){
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            }
        });

        t.start();
        while (true){
            System.out.println(" "+t.getState());
            Thread.sleep(1000);

        }

    }
}

9.线程安全

  • 不安全的原因:
  • 1.抢占式执行。(万恶之源)
  • 2.多个线程修改同一个变量
  • 3.修改操作不是原子的
  • 4.内存可见性(编译器优化)
  • 5.指令重排序(编译器优化)

9.1两个线程分别增加5000,实际结果不是10000

/**
 * User:yang
 */
class Counter {
    public static int count=0;


    public static void increase(){
        count++;

    }
}
public class ThreadDemo12 {
    public static void main(String[] args) throws InterruptedException {
        Counter counter=new Counter();

        Thread t1=new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    counter.increase();
                }
            }
        };
        Thread t2=new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    counter.increase();
                }
            }
        };
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(counter.count);
    }
}

10.线程安全的解决办法(synchronize)

10.1synchronize(关键字) 监视器锁(atm取钱)

  • 功能:保证操作的原子性,禁止指令重排序,保证内存可见性

10.2修饰一个方法

相当于加了LOCK,UNLOCK


  synchronized  public   void increase(){
        count++;

    }

10.3修饰一个代码块

   public void increase() {
        synchronized (this) {
            count++;
        }
    }
Thread t2 = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    synchronized(counter){
                        counter.increase();
                    }
                }
            }
        };

10.4嵌套加锁

  • synchronized内部进行了特殊处理,可重入锁。
  • 在这里插入图片描述
/**
 * User:yang
 */
class Counter {
    public static int count = 0;
//      public   void increase(){
//        count++;
//
//    }

    synchronized void increase() {
        count++;

    }

//    public void increase() {
//        synchronized (this) {
//            count++;
//        }
//    }
}

public class ThreadDemo12 {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        Thread t1 = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    synchronized (counter) {
                        counter.increase();
                    }
                }
            }
        };
        Thread t2 = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    synchronized (counter) {
                        counter.increase();
                    }
                }
            }
        };
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(counter.count);
    }
}

11.volatile(比synchronized更轻量)

  • 效果:辅助保证线程安全
  • 作用:禁止指令重排序,保证内存可见性,但是不保证原子性
  • 主要用于读写同一个变量的时候
  • 当两个线程都要写的时候,volatile无能为力,要用synchronized
import java.util.Scanner;

/**
 * User:yang
 */
public class ThreadDemo13 {
   static class Counter{

   volatile      public int  flag=0;
    }

    public static void main(String[] args) {
        Counter counter=new Counter();
        Thread t1=new Thread(){
            @Override
            public void run() {
                while (counter.flag==0){

                }
                System.out.println("线程1  循环结束");
            }
        };t1.start();
        Thread t2=new Thread(){
            @Override
            public void run() {
                Scanner scanner=new Scanner(System.in);
                System.out.println("please input an int ");
                counter.flag=scanner.nextInt();
            }
        };t2.start();
    }
}

12.wait/notify

  • wait,notify都必须在synchronized里面使用

12.1wait

  • 1.释放锁
  • 2.等待其他线程的通知
  • 3.等通知来了之后,重新尝试获取锁
  • 必须在synchronized里面使用

12.2notify

  • 作用:通知某个线程从wait醒来
  • 必须在synchronized里面使用
  • 调用notify方法之后,代码不会立即释放锁,而是执行完synchronized之后才释放锁。同时等待的线程们就尝试重新竞争这个锁
/**
 * User:yang
 */
//wait   notify   用法
public class ThreadDemo15 {
    static public Object locker = new Object();

    //用来等待的线程
    static class WaitTask implements Runnable {
        @Override
        public void run() {
            synchronized (locker) {
                while (true) {
                    System.out.println("wait 开始");
                    try {
                        locker.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("wait 结束");
                }
            }
        }
    }

    //用来通知的线程
    static class NotifyTask implements Runnable {
        @Override
        public void run() {

            synchronized (locker) {
                System.out.println("notify 开始");
                locker.notify();
                System.out.println("notify 结束");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new WaitTask());
        Thread t2 = new Thread(new NotifyTask());
        t1.start();
        Thread.sleep(3000);
        t2.start();
    }
}

12.3notifyAll

  • 将所有waiting变成就绪,然后只有一个竞争到,竞争失败的就会blocked

13.注意

  • 调用wait/notify/加锁synchronized都是针对同一个对象进行

14.JMM

Java Memory Model Java内存模型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值