java笔记35,线程

线程

注意:

  1. run()方法和start()方法的区别
    run方法相当于普通方法调用,还是单线程,start方法才是多线程,启动线程由jvm运行run方法
  2. java的线程调度模型,使用的是优先级抢占式调度
  3. 接口实现会导致无法使用Thread类中一些方法,可使用Thread.currentThread.方法名来继续使用

多线程有两种实现方式
方式1:继承Thread类:class test2 extends Thread
方式2:实现runable接口:class test2 implements Runnable

runnable接口实现多线程有点特殊

 // Runnable接口实现线程方式有点不一样
        test2 t2= new test2();
        Thread t3=new Thread(t2);
        Thread t4=new Thread(t2);

        t3.start();
        t4.start();

继承Thread类实现多线程

public class test1 {
    public static void main(String[] args){
        test2 t2=new test2();
        t2.start();
        while (true)
        {
            System.out.println("this is main");
        }
    }
}
class test2 extends Thread
{
    @Override
    public void run() {
        while (true)
        {
            System.out.println("我是线程");
        }
    }
}

Thread方法

getName()
setName()
可以看到,可以设置线程同名

public class test1 {
    public static void main(String[] args){
        test2 t2=new test2();
        System.out.println(t2.getName());
        // 给t2线程设置名称
        t2.setName(new String("张三"));
        System.out.println(t2.getName());

        // 给俩线程设置同名会如何?
        test2 t3=new test2();
        t3.setName(new String("张三"));
        System.out.println(t3.getName());
        System.out.println(t2.getName());
    }
}

带参构造方法
Thread类中有带参构造可以直接指定线程名,但是我们Thread子类test2没有带参构造
所以需要写出带参构造,直接传给super就行

public class test1 {
    public static void main(String[] args){
       test2 t2=new test2("线程1");
       System.out.println(t2.getName());
    }
}
class test2 extends Thread
{
    test2(String name)
    {
        super(name);
    }
    //..............

currentThread()

Thread中的静态方法,用于返回当前正在执行的线程对象

public class test1 {
    public static void main(String[] args){
        System.out.println(Thread.currentThread().getName());
    }
}

线程优先级

我们知道java中的线程使用的是抢占式线程调度方式,所以需要根据优先级来判断线程的执行顺序
线程默认优先级:5
线程最低优先级:1
线程最高优先级:10
优先级,只能说明它获取cpu资源概率高,而并非一定,所以依然会出现,优先级低的先运行

getPriority()
setPriority(int)
使用该两方法设置线程的优先级

public class test1 {
    public static void main(String[] args){
        test2 t2=new test2("优先线程");
        test2 t3=new test2("后置线程");
        System.out.println(t2.getPriority()+" "+t3.getPriority());
        t2.setPriority(10);
        System.out.println(t2.getPriority()+" "+t3.getPriority());

        // 初步运行,由于t2还没进入运行,所以先执行了t3,t2一进入,就抢占了t3的运行,直到t2运行结束
        t3.start();
        t2.start();
    }
}

Sleep方法

需要抛出异常
Thread.Sleep(long time);

          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }

join方法

只有join的线程结束后,其他线程才可以执行
返祖操作,返回单线程

public class test1 {
    public static void main(String[] args) throws InterruptedException {
        test2 t2=new test2("优先线程");
        test2 t3=new test2("后置线程");

        t2.start();
        t2.join();// 设置只有t2运行完了,t3才可以运行
        t3.start();
    }
}

setDaemon,设置守护线程

主线程挂它也挂,当只剩下守护进程,程序结束

public class test1 {
    public static void main(String[] args) throws InterruptedException {
        test2 t2=new test2("优先线程");
        test2 t3=new test2("后置线程");
        
        // 设置为守护线程
        t2.setDaemon(true);
        t3.setDaemon(true);

        t2.start();
        t3.start();
    }
}

同步代码块,同步锁

为了使多线程修改同一数据不会造成:读脏数据,重复修改,等错误
给修改数据的代码块加锁
obj是同一个,就代表同一把锁
synchronized (obj) {被枷锁代码}

public class test1 {
    public static void main(String[] args) throws InterruptedException {

        // Runnable接口实现线程方式有点不一样
        test2 t2= new test2();
        Thread t3=new Thread(t2);
        Thread t4=new Thread(t2);

        t3.start();
        t4.start();
    }
}
class test2  implements Runnable
{
    public static int num=100;
    // 这个obj对象随便new的
    public Object obj=new Object();
    test2()
    {}
    @Override
    public void run() {
        while (num>0)
        {
            // 被加锁的代码块,一次只能有一个线程在执行
            synchronized (obj) {
                System.out.println(Thread.currentThread().getName() + " " + num);
                num--;
            }
        }
    }
}

自动同步的数据结构(线程安全),都是使用synchronized 实现同步
StringBuffer
vector
Hashtable
使用这几个结构,将会自动同步

Lock锁,Lock接口

更贴近自然语言的方式

Lock lock=new ReentrantLock();
        lock.lock();
        // 这部分的代码将被锁住
        // 这部分代码一次只运行一个线程运行
        lock.unlock();

如果在lock中间部分出现错误,unlock将无法执行到
所以,最好在外面套一层try catch

线程阻塞与执行

要注意,这些操作是对本线程内的,也就是说,如果wait了,就不执行下面的语句了

		try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            
		notifyAll();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值