java 笔记 线程5
线程安全问题就是是 多个线程访问同一个 共享资源 ,如果多个线程不同步数据的话,会出现问题,可以用 synchronized(对象)同步数据维护数据。synchronized机制是给共享资源上锁,在执行之前要拿到同步对象的锁(一个对象一把锁)才可以执行同步的内容,在执行过程中不会被其他线程参与进来,同步代码在同一刻只执行一个线程,而且也同步了共享资源,只有拿到锁的线程才可以访问共享资源,这样就可以强制使得对共享资源的访问都是顺序的,线程执行完就把锁还给对象了,也就是执行同步代码前拿到锁,执行时锁锁住了,其他线程参与不进来,执行完就还给对象锁。{:10_243:} 同步代码格式:
synchronized(对象) { 需要同步的代码; }
同步函数格式:
修饰符synchronized void函数名{
}
{:10_249:} 同步的前提:
同步需要两个或者两个以上的线程。
多个线程共享同一个数据的时候使用的是同一个锁(有多个线程 共享数据的时候要共享同一个对象 ,如果都是同步代码synchronized(对象),填的对象一样,如果有同步代码和同步函数同步函数同步的是什么对象 同步代码synchronized(对象)就写哪个对象)
举例子:
在同步函数中。函数都会被一个对象调用,那那个对象就是this,同步韩苏护的锁就是this,在一个类里有同步代码同步函数,既然函数的对象是this,锁是this ,同步代码就写this
在静态函数中,锁是class对象,静态内存是,内存中没有本类对象,但是一定有改类对应的字节码文件对象也就是写 本类名。Class
单例设计模式-饿汉式和懒汉式
饿汉式:
Class Single
{
private static finalsingle s=new single();
private Single(){}
public static Single getInstance(){
return s;
}
}
懒汉式:
public static void main(String[] args) {
System.out.println("Hello World");
}
}
classSingle
{ private static Single s=null;
private Single(){}
public staticSingle getInstance(){
if(s==null)
s=new Single();
return s;
}
}
懒汉式和饿汉式有什么不同:
懒汉式是用于延迟加载
但在多线程中懒汉式会有安全性 解决方法就是同步同步的话可以解决这个问题
但是会稍微有点低效 因为其他线程进来后先同步 ,可以用双重判断 加同步的时候锁是该类所属的字节码对象
解决后:
public static void main(String[] args) {
System.out.println("Hello World");
}
}
classSingle
{
private static Single s=null;
private Single(){}
public staticSingle getInstance(){
if (s==null)
{
synchronized(Single.class)
{
if(s==null)
s=new Single();
}
}
return s;
}
死锁:
package UI;
import java.lang.Thread;
public class sport {
public static void main(String[] args) {
Ticketa=new Ticket();
Ticketb=new Ticket();
Thread b1 =new Thread(a);
Thread b2 =new Thread(a);
b1.start();
try { Thread.sleep(10);} catch (Exception e){};
a.flag=false;
b2.start();
}
}
class Ticket implements Runnable
{
private int ticket=100;
boolean flag =true;
Object obj =new Object();
public void run(){
if(flag){
while(true){
synchronized(obj){//把这里obj 改成this
show();//调用的show的是this的锁
}
}
}
else
while(true)
show();
}
public synchronized void show(){//this
synchronized(obj){//这里也改为this
if(ticket>0){
try { Thread.sleep(10);} catch (Exception e){};
System.out.println(Thread.currentThread().getName()+"…sale:"+ticket--);
}
}
}
}
结果是 程序会挂着执行不完
死锁:
同步中嵌套同步 同步不同
上面例子有两重锁 ,锁都是不同对象的,那就同步不了数据 ,那就是死锁了
页:
[1]