同步的问题
看一段代码
class MyThread implements Runnable{
private int ticket=5;
@Override
public void run() {
while (true){
if (this.ticket>0){
try {
Thread.sleep(100);//模拟延迟操作
} catch (InterruptedException e) {
e.printStackTrace();
}
this.ticket--;
System.out.println(Thread.currentThread().getName()+"卖票:"+this.ticket);
}else{
System.out.println("票卖光了");
break;
}
}
}
}
public class Main{
public static void main(String[] args) {
MyThread mt=new MyThread();
new Thread(mt,"票贩子A").start();
new Thread(mt,"票贩子B").start();
new Thread(mt,"票贩子C").start();
}
}
以上代码很可能会出现负数,或者卖出不止5次票
这个问题需要用同步进行等待,如果想要在程序中实现同步功能可以使用synchronized关键字来实现
在同步代码块的操作里面的代码只允许一个线程执行
class MyThread implements Runnable{
private int ticket=5;
@Override
public void run() {
while (true){
synchronized (this){//在这个代码块中表示每一次只能允许一个线程进行访问
if (this.ticket>0){
try {
Thread.sleep(100);//模拟延迟操作
} catch (InterruptedException e) {
e.printStackTrace();
}
this.ticket--;
System.out.println(Thread.currentThread().getName()+"卖票:"+this.ticket);
}else{
System.out.println("票卖光了");
break;
}
}
}
}
}
public class Main{
public static void main(String[] args) {
MyThread mt=new MyThread();
new Thread(mt,"票贩子A").start();
new Thread(mt,"票贩子B").start();
new Thread(mt,"票贩子C").start();
}
}
加入同步处理之后,程序的整体性能下降了,同步实际上会造成性能的降低
也可以在如下方法使用
把sysnchronized放在方法前面
class MyThread implements Runnable {
private int ticket = 10;
public synchronized void sale() {
while (true) {
//在这个代码块中表示每一次只能允许一个线程进行访问
if (this.ticket > 0) {
try {
Thread.sleep(100);//模拟延迟操作
} catch (InterruptedException e) {
e.printStackTrace();
}
this.ticket--;
System.out.println(Thread.currentThread().getName() + "卖票:" + this.ticket);
} else {
System.out.println("票卖光了");
break;
}
}
}
@Override
public void run() {
this.sale();
}
}
public class Main {
public static void main(String[] args) {
MyThread mt = new MyThread();
new Thread(mt, "票贩子A").start();//必须是同一个对象
new Thread(mt, "票贩子B").start();
new Thread(mt, "票贩子C").start();
}
}
系统中许多类上使用的同步处理采用的都是同步方法
死锁
死锁是在进行多线程同步的处理之中有可能产生的一个问题,所谓死锁指的是若干个线程,彼此互相等待的概念,过多的同步操作会造成死锁。
以下代码可能会造成死锁的情况
class A{
public synchronized void say(B b){
System.out.println("a先生说:把你的本给我,我给你笔,否则不给");
b.get();
}
public synchronized void get(){
System.out.println("A先生得到本,付出了笔");
}
}
class B{
public synchronized void say(A a){
System.out.println("b:先生说:把你的笔给我");
a.get();
}
public synchronized void get(){
System.out.println("B先生得到了笔,付出了本");
}
}
public class Main implements Runnable{
private static A a=new A();
private static B b=new B();
public static void main(String[]args)throws Exception{
new Main();
}
public Main(){
new Thread(this).start();
b.say(a);
}
@Override
public void run() {
a.say(b);
}
}
执行结果可能是
b:先生说:把你的笔给我
a先生说:把你的本给我,我给你笔,否则不给
由于俩个类都使用了同步方法定义,就会造成a对象等待b对象执行完毕,而b对象等待a对象执行完毕,这样就会造成死锁的现象
根本原因是synchronized锁方法的时候是给当前对象加锁,想要执行必须获得当前对象的锁,但俩个方法都互相持有对方想要获取的对象的锁,都拿在手里,去获取对方手里的锁,所以很有可能会造成死锁