线程和同步

一、线程

1.1 多线程

自定义线程类:

	public class MyThread extends Thread{
		public MyThread(String name){      
			super(name);          
		}   
		public void run(){             
			for (int i = 0; i < 20; i++) {         
				System.out.println(getName()+i);             
			 }          
		}    
	}

测试

public class Demo1 {     
	public static void main(String[] args) {        
		System.out.println("main线程");        
	    MyThread mt = new MyThread("新线程");                   
	    mt.start();//开启了一个新的线程           
	    for (int i = 0; i < 20; i++) {      
	    System.out.println("main:"+i);             
	     }         
	 }    
  }   

1.2 thread

(1)构造方法
public Thread() :分配一个新的线程对象。
public Thread(String name) :分配一个指定名字的新的线程对象。
public Thread(Runnable target) :分配一个带有指定目标新的线程对象。
public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字。
(2)常用方法
public void start() :线程开始执行, Java虚拟机会调用此线程的run方法。
public void run() :此线程要执行的任务在此处定义代码。
public static void sleep(long millis) :停止执行millis秒。
public String getName() :获取当前线程名称。
public static Thread currentThread() :返回对当前正在执行的线程对象的引用。
setDaemon(), 设置一个线程为守护线程, 该线程不会单独执行, 当其他非守护线程都执行结束后,
自动退出。
join(int), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续 可以等待指定的毫秒.

1.3 Runable

定义Runnable接口的实现类,并重写该接口的run()方法. 创建Runnable实现类的实例,将此实例带入Thread的构造方法中,,然后调用线程对象的start()方法来启动线程。

public class MyRunnable implements Runnable{ 
		@Override     
		 public void run() {      
		 		for (int i = 0; i < 20; i++) {          			             
		 				System.out.println(Thread.currentThread().getName()+" "+i);              
		 		}         
		  }     
}

测试

public class Demo {    
		public static void main(String[] args) {              
		 		MyRunnable mr = new MyRunnable();         
		 		//创建线程对象         
		 		Thread t = new Thread(mr, "小强");         
		 		t.start();         
		 		for (int i = 0; i < 20; i++) {             
		         		System.out.println("旺财 " + i);         
		        }     
	   } 
 }

1.4 Thread和Runnable的区别

实现了Runable接口能实现资源共享。避免了单继承的局限,. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

二、线程安全

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写 操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步, 否则的话就可能影响线程安全。 Java中提供了同步机制 (synchronized)来解决这种问题。

2.1 synchronized

synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。
(1)同步代码块

		synchronized(同步锁){      
					同步操作的代码
		}

同步锁:对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁.

  1. 锁对象 可以是任意类型。
  2. 多个线程对象 要使用同一把锁。

注意:在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着。
(2)同步方法

public synchronized void method(){    
		 可能会产生线程安全问题的代码  
 }

对于非static方法,同步锁就是this。
对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。

2.2 Lock锁

public void lock() :加同步锁。
public void unlock() :释放同步锁

2.3 Lock锁和sychronized的区别

synchronized既可以加在方法上,也可以加载特定代码块上,而lock需要显示地指定起始位置和终止
位置。
synchronized是托管给JVM执行的,lock的锁定是通过代码实现的,它有比synchronized更精确的线
程语义。
性能上的不同:lock接口的实现类ReentrantLock,不仅具有和synchronlzed相同的并发性和内存语义,还多了超时的获取锁、定时锁、等候和中断锁等。在竞争不是很激烈的情况下,synchronized的性能
优于ReentrantLock,竞争激烈的情况下synchronized的性能会下降的非常快,而ReentrantLock则基本不变。
锁机制不同:synchronized获取锁和释放锁的方式都是在块结构中,当获取多个锁时,必须以相反的顺序释放,并且是自动解锁。而Lock则需要开发人员手动释放,井且必须在finally中释放,否则会引起死锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值