java的线程之间资源共享,所以会出现线程同步问题(即,线程安全)

一、线程创建:

方式①:extends java.lang.Thread,重写run(),run方法里是开启线程后要做的事。.start()启动线程,执行run()里的程序。

方式②:implements java.lang.runnable,实现run(); 然后new Thread(implements产生的线程); 调用.start()启动线程

Thread的方法:

.run() 定义线程要做的事

.start() 启动线程

.sleep()方法使线程进入阻塞状态,当sleep结束后,线程进入就绪状态,继续执行接下来的程序。

.wait() 线程等待

sleep和wait的区别:

.join() :当程序执行过程中调用了其他线程的join()方法时,则当前线程被阻塞,直到执行join()的线程 结束为止。也就是说join方法使一个线程等待另一个线程完成。

.setDaemon(boolean): Daemon守护神。将此线程设置为守护线程。主线程死亡时,守护线程必须死亡,无论是否执行完。当守护线程比主线程执行的快时,可能会比主线程先死。

.interrupt():友好的中断自己

.stop():强制中断线程,不友好

.notify():唤醒线程

.interrupted():可清除线程的中断状态,即,将线程状态改为非中断

.isInterrupted():线程的中断状态不受影响:返回线程的状态:是否中断。不会对线程的现有状态有影响。

二、线程同步(线程安全)

多个线程同时对同一个对象的实例变量进行操作时,会引起同步问题(和操作系统中的进程同步问题是一样的道理,同步问题:数据脏读、不可重复读、丢失更新等)。

解决的方法就是加锁:方法①在java里很简单,给某个方法or某段代码or某个变量加上synchronized关键字,即加锁。

“同步代码块”:给整个方法加锁,那么,进入这个方法的程序都要等待上一个程序释放这个资源,等待的时间太长,效率就低。所以常用的是只给方法中的某段代码加锁。也就是“同步代码块”:写法:synchronized (this) {需要加锁的某段代码}

同步锁”:java5之后使用ReentrantLock对象和方法加锁。如下:



1 //方法3:同步锁
 2     public ReentrantLock reentrantLock=new ReentrantLock();
 3     
 4     public /*加锁方法1:synchronized*/ void getMoney(String name) {
 5         //加锁方法2:synchronized (this) {
 6         
 7         reentrantLock.lock();
 8         try {
 9             if (money > 1500) {
10                     money -= 1500;
11                     System.out.println(name + "取款1500成功!");
12                 } else {
13                     System.out.println(name + "余额不足!");
14                 }
15         } catch (Exception e) {
16             e.printStackTrace();
17         } finally{//finally的作用:即使出现异常了,也可以执行解锁的方法unlock()
18             reentrantLock.unlock();
19         }
20         
21         //}
22     }



Collections类提供了使之可以变得线程安全的方法。如下:



1 List<String> list=Collections.synchronizedList(new ArrayList<String>());