0:只要涉及到同时执行的那么就要就是多线程的,例如四个窗口同时卖票
1:实现多线程的方法有两种一个中是extends Thread,第二种是implement Runnable
如果解释的话就是:
第一种方式,线程任务和线程是绑定在一起的,创建了四个线程就创建了4份资源
第二种方式,线程任务和线程对象进行了分离,只需要创建一个任务对象(只有一个份资源),分别让四个线程去执行。
这样就会发现,但一个进行进行到一般的时候,例如在输入的时候,cpu 被其他的进程抢去了,然后才又回来执行
为了解决这种同步的问题,引入synchronized的,同步,
synchronized 的方法里面的东西,要执行必须全部执行完了,就和数据库事务有点像,或者说有点向上厕所,这个人上完了,别人才能上,总不能别人上一半的呢,你抢先去了把。synchronized 可以用来修饰方法,该方法的锁其实就是this,如果是静态的方法,那么锁就是类的class
所以现在其实就是将刚才要输出的东西使用这个synchronized(obj)来括一下,
一个实例:一个银行可以存钱,两个人同时存钱,每个人存3次,每次存100
3:synchronized修饰的函数为同步函数,同步函数的同步锁是什么?是this,
但是如果是静态的同步函数,那么同步锁就是该类的class
5:单例模式里面的并发的安全问题,
懒汉式中有:
1:实现多线程的方法有两种一个中是extends Thread,第二种是implement Runnable
如果解释的话就是:
第一种方式,线程任务和线程是绑定在一起的,创建了四个线程就创建了4份资源
第二种方式,线程任务和线程对象进行了分离,只需要创建一个任务对象(只有一个份资源),分别让四个线程去执行。
//第一种方法如下:每个窗口都有50张票
class Ticket1 extends Thread{
int num=50;
public void run(){
while(true){
if (num>0)
System.out.println(Thread.currentThread().getName()+" sale "+num--);
}
}
}
Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
t1.start();
t2.start();
//第二种方法如下:几个窗口一共是50张票
class Ticket implements Runnable{
int num=50;
public void run(){
while(true){
if (num>0)
System.out.println(Thread.currentThread().getName()+" sale "+num--);
}
}
}
//注意这里只有一个Ticket的对象,然后创建Thread的时候都是用的这个Ticket,不管是多少个窗口
Ticket ticket = new Ticket();
Thread t1 = new Thread(ticket);
Thread t2 = new Thread(ticket);
t1.start();
t2.start();
2: 如果一起执行的里面只有一句话那么就没有同步的问题,
为了模仿同步问题,我们在
if (num>0)
System.out.println(Thread.currentThread().getName()+" sale "+num--);
//下面继续执行:
if(num>0){
System.out.print(" **********"+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.println(""+num);
}
这样就会发现,但一个进行进行到一般的时候,例如在输入的时候,cpu 被其他的进程抢去了,然后才又回来执行
为了解决这种同步的问题,引入synchronized的,同步,
synchronized 的方法里面的东西,要执行必须全部执行完了,就和数据库事务有点像,或者说有点向上厕所,这个人上完了,别人才能上,总不能别人上一半的呢,你抢先去了把。synchronized 可以用来修饰方法,该方法的锁其实就是this,如果是静态的方法,那么锁就是类的class
所以现在其实就是将刚才要输出的东西使用这个synchronized(obj)来括一下,
class Ticket implements Runnable{
int num=50;
Object obj = new Object();
public void run(){
while(true){
synchronized(obj){
if (num>0)
System.out.print(Thread.currentThread().getName()+" sale "+num--+"$$$$$$$$$$$");
if(num>0){
System.out.print(" **********"+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.println(""+num);
}
}
}
}
}
一个实例:一个银行可以存钱,两个人同时存钱,每个人存3次,每次存100
public class SaveMoney{
public static void main(String[] args){
Person person = new Person();
Thread t1 = new Thread(person);
Thread t2 = new Thread(person);
Thread t3 = new Thread(person);
t1.start();
t2.start();
t3.start();
}
}
class Person implements Runnable{
Bank bank = new Bank();
int times = 3;
public void run(){
//存钱100一次,一共3次
for(int i=0;i<3;i++)
bank.add(100);
}
}
class Bank{
int sum = 12345;
public synchronized void add(int addedNumber){
System.out.print(Thread.currentThread().getName()+" 存之前的余额为"+sum);
sum = sum+addedNumber;
System.out.println(" 当前的余额为"+sum);
}
}
3:synchronized修饰的函数为同步函数,同步函数的同步锁是什么?是this,
但是如果是静态的同步函数,那么同步锁就是该类的class
class Ticket implements Runnable{
static int num = 50;
boolean flag = true;
public void run(){
if(flag==true){
while(true){
synchronized(Ticket.class){
try{
Thread.sleep(20);
}catch(Exception e){
//
}
if(num>0){
System.out.print(Thread.currentThread().getName()+" sale "+num--);
}
if(num>0){
System.out.print(" **********"+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.println(""+num);
}
}
}
}else{
while(true){
fun();
}
}
}
public synchronized static void fun(){
try{
Thread.sleep(20);
}catch(Exception e){
//
}
if(num>0){
System.out.print(Thread.currentThread().getName()+" sale "+num--);
}
if(num>0){
System.out.print(" -----------------------------------------"+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.print(""+num);
System.out.println(""+num);
}
}
}
public class SaleTicket{
public static void main(String[] args){
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(20);}catch(Exception e){}
t.flag=false;
t2.start();
}
}
/**模拟死锁的情况,
A要上楼,B要下楼,A在1层,B在4层,2层和3层有锁
A上楼的顺序是要2楼的钥匙,然后是3楼的,B下楼是先3楼,然后2楼。
顺利的情况是A 拿了2楼的钥匙,然后拿了三楼的钥匙,然后B 开始下楼哪了3楼的钥匙,然后是2楼的钥匙
所以就会出现两个人,A有了2楼的钥匙,但是要3楼的钥匙,B有了3楼的钥匙,但是要2楼的钥匙
*/
public class DeadLock{
public static void main(String[] args){
Test test = new Test();
Thread t1 = new Thread(test);
Thread t2 = new Thread(test);
test.flag = 0;
t1.start();
//让主线程睡一会儿,那么就会执行上面的start的方法了,不然不执行的
try{Thread.sleep(500);}catch(Exception e){}
test.flag=1;
t2.start();
}
}
class Test implements Runnable{
int flag;
Object lock1 = new Object();
Object lock2 = new Object();
public void run(){
if(flag==0){
while(true){
synchronized(lock1){
try{
Thread.sleep(50);
}catch(Exception e){
//
}
System.out.println("Flag = 1 已经有了lock1了,现在要lock2");
synchronized(lock2){
System.out.println("Flag = 1 获取了lock2");
}
}
}
}else{
while(true){
synchronized(lock2){
try{
Thread.sleep(50);
}catch(Exception e){
//
}
System.out.println("Flag = 2 已经有了lock2了,现在要lock1");
synchronized(lock1){
System.out.println("Flag = 1 获取了lock1");
}
}
}
}
}
}
5:单例模式里面的并发的安全问题,
懒汉式中有:
public class SingleTest{
public static void main(String[] args){
Test test = new Test();
Thread t1 = new Thread(test);
Thread t2 = new Thread(test);
Thread t3 = new Thread(test);
Thread t4 = new Thread(test);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Test implements Runnable{
public void run(){
Single single = Single.getInstance();
System.out.println(""+single.toString());
}
}
class Single{
private static Single single;
private Single(){}
public synchronized static Single getInstance(){
if(single==null){
single= new Single();
return single;
}else
return single;
}
}