多线程中的知识点总结

知识点一:

多线程中锁的认识:(synchronized)
1.锁是什么?
	锁是一个独一无二标识
2.锁跟对象的关系
	对象在内存中是独一无二的,所有一般把对象当成锁,锁信息可以存在对象头中
3.锁的作用范围
	锁一般作用于方法或者代码块上;一把锁可以用在不同的方法上
//例1
Class A{

	private B b=new B("张三");
	
	public static void start(){
		new Thread(()->thread1(),"Thread1").start();
		new Thread(()->thread2(),"Thread2").start();
	}
	//线程Thread1中的方法
	synchronized thread1(){
		//睡5秒
		Thread.sleep(5000)
		//获取b对象中的name属性
		b.getName().sout
	}
	
	//线程Thread2中的方法
	thread2(){
		b.setName("李四")
	}
}

//例1结果分析:
therad1中的synchronized是以A类对象作为锁,thread2方法中没有上锁;所以不存在锁资源竞争,输出结果为:李四

//例2
Class A{

	private B b=new B("张三");
	
	public static void start(){
		new Thread(()->thread1(),"Thread1").start();
		new Thread(()->thread2(),"Thread2").start();
	}
	//线程Thread1中的方法
	synchronized thread1(){
		//睡5秒
		Thread.sleep(5000)
		//获取b对象中的name属性
		b.getName().sout
	}
	
	//线程Thread2中的方法
	thread2(){
		synchronized(b){
			b.setName("李四")
		}
	}
}
//例2结果分析
therad1中的synchronized是以A类对象作为锁,thread2方法中以对象b作为锁;所以也不存在锁资源竞争,输出结果为:李四

知识点二:

	synchroniced锁在对象间是否具备传递性?
Class A{
	private B b;
	
	public synchronized void test(){
	} 
	public void test2(){
		synchronized(b){
		}
	}
}
//分析:
test的锁对象为a,test2的锁对象为b,a中有属性b,当不同线程同时调用test()test2()是否存在竞争关系呢?
对象a和对象b是不同的对象,所以两个方法使用的锁不一样,因此不存在竞争关系,所以不存在传递性。

知识点三:

	两个线程同时对相同的资源进行更改,其中一个线程调用sleep()那么,当前线程的锁资源会不会释放
Class A{

	private B b=new B("张三");
	
	public static void start(){
		new Thread(()->thread1(),"Thread1").start();
		Thread.sleep(100);//先让线程Thread1抢到资源
		new Thread(()->thread2(),"Thread2").start();
		new Thread(()->thread3(),"Thread3").start();//实时查看b的值
	}
	//线程Thread1中的方法
	synchronized thread1(){
		b.setName("李四");
		//睡5秒
		Thread.sleep(1000000000000000000000)
		//获取b对象中的name属性
		System.out.println(b.getName());
	}
	
	//线程Thread2中的方法
	synchronized thread2(){
		b.setName("王五");
		System.out.println(b.getName());
	}
	//线程Thread3中的方法
	synchronized thread3(){
		while(true){
			System.out.println(b.getName());
		}
	}
}

//获取的结果永远是李四:
	synchronized中sleep不会释放资源,wait会释放资源。

知识点四:

thread.sleep(1000)究竟是哪个线程在sleep
class A{
	public static void main(){
		Thread thread1=new Thread1();
		Thread thread2=new Thread2();
		thread1.start();
		thread2.start();
		thread1.sleep(5000);
		thread2.sleep(5000);
		System.out.println("end");
	}
}

Class Thread1 extends Thread{
	public void run(){
		super.run();
		for(int i=0;i<100000;i++){System.out.println(i) }
	}
}

Class Thread2 extends Thread{
	public void run(){
		super.run();
		for(int i=0;i<100000;i++){System.out.println(i) }
	}
}
//分析
	在main方法中,主线程main启动了两个线程thread1和thread2,thread1和thread2调用sleep()5秒,其实在运行的过程中由于在主线程的方法中调用了sleep所以sleep作用在主线程。主线程睡了10000秒;
//结论
	sleep()在哪个线程被调用,就作用于哪个线程,跟线程对象无关

知识点五:

1.interrupt()和isInterrupted()和interrupted()的用法
	interrupt()给线程加入一个中断标记,并不会向stop()一样直接终止当前线程
	isInterrupted();判断当前线程是否有interrupt标记,有的话返回true,没有返回false
	interrupted();跟isInterrupted()用法一样,封装了isInterrupted();
	
2.如果一个线程在sleep,此时给它加一个终止标记,会直接抛出interruptedException异常,并且此线程不能被标记为interrupt
//例1:结果从1输出到100000
Class A{
	public static void main(){
		Thread thread1=new Thread(()->{
			for(int i=0;i<100000:i++){
				System.out.println(i);
			}
		},"thread1");
		//启动线程1
		thread1.start();
		//主线线程睡3豪秒
		Thread.sleep(3)
		//给线程thread1加一个终止的标记
		thread1.interrupt();
	}	
}
//例2:结果从1输出到198
Class A{
	public static void main(){
		Thread thread1=new Thread(()->{
			for(int i=0;i<100000:i++){
				//判断当前线程thread1是否有终止标记
				if(Thread.interrupted()){break;}
				System.out.println(i);
			}
		},"thread1");
		//启动线程1
		thread1.start();
		//主线线程睡3豪秒
		Thread.sleep(3)
		//给线程thread1加一个终止的标记
		thread1.interrupt();
	}	
}
//例3
Class A{
	public static void main(){
		Thread thread1=new Thread(()->{
		try{
			System.out.println("thread1 start")
			Thread.sleep(2000000);
			System.out.println("thread1 end")
		}catch(InterruptedException e){
			System.out.println("thread1 在沉睡时被加interrupt标记");
			System.out.println(Thread.interrupted());//查看当前thread1是否被标记上interrupt
		}
		
		},"thread1");
		//启动线程1
		thread1.start();
		//主线线程睡3豪秒
		Thread.sleep(3)
		//给线程thread1加一个终止的标记
		thread1.interrupt();
		System.out.println("main end")
	}	
}

//输出结果为:
	thread1 start
	main end
	thread1 在沉睡时被加interrupt标记
	false

知识点六:

线程的的权重:1-10,默认为5权重越搞cpu资源分配越多。
Class A{
	public static void main(){
		//定义线程1
		Thread thread1 = new Thread(()->{
            int count=0;
          while (true){
            count++;
            if(Thread.interrupted()){
                System.out.println(Thread.currentThread().getName()+"#"+Thread.currentThread().getPriority()+"#"+count);
                break;
            }
          }
        },"thread1");
		//定义线程2
        Thread thread2 = new Thread(()->{
            int count=0;
            while (true){
                count++;
                if(Thread.interrupted()){
                    System.out.println(Thread.currentThread().getName()+"#"+Thread.currentThread().getPriority()+"#"+count);
                    break;
                }
            }
        },"thread2");
		
		//设置权重
        thread1.setPriority(Thread.NORM_PRIORITY+3);
        thread2.setPriority(Thread.NORM_PRIORITY-3);
        thread2.start();
        thread1.start();
        Thread.sleep(5000);
        thread2.interrupt();
        thread1.interrupt();
	}	
}

//输出结果:
	thread1#8#839523159
	thread2#2#820685026

知识点七:

守护线程daemon--当没有其他非守护线程运行时,守护线程就会自动终止
Class A{
	//定义一个thread1
	Thread thread1=new Thread(()->{
		for(int i=0;i<20;i++){
			Thread.sleep(1000);
			System.out.println(i);
		}
		},"thread1");
	//将thread1设置为守护线程
	thread1.setDaemon(true);
	thread1.start();
	//主线程睡5秒结束
	Thread.sleep(5000);
	System.out.println("主线程mian结束啦");
}
//打印结果
	0
	1
	2
	3
	4
	主线程mian结束啦
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值