文章目录
- Synchronized和Lock的区别是什么?
- 案例一
- 方法一 继承Thread类
- 方法二 实现Runnable接口
- 案例二
- 方法一 继承Thread类
- 方法二 实现Runnable接口
- 案例三
- 方法一 继承Thread类
- 方法二 实现Runnable接口
- 案例四
- 方法一 继承Thread类
- 方法二 实现Runnable接口
- 案例五
- 方法一 继承Thread类
- 方法二 实现Runnable接口
- 案例六
- 方法一 继承Thread类
- 方法二 实现Runnable接口
- 案例七
- 方法一 继承Thread类
- 方法二 实现Runnable接口
- 案例八
- 方法一 继承Thread类
- 方法二 实现Runnable接口
- 案例九
- 方法一 继承Thread类
- 方法二 实现Runnable接口
Synchronized和Lock的区别是什么?
1.synchronized是Java中的关键字,是jdk自带的;Lock是一个接口
2.synchronized在线程执行发生异常时,jvm会让线程释放锁,因此不会导致死锁现象发生;Lock在finally中必须通过unLock()去释放锁,不然容易造成线程死锁
3.使用synchronized时,如果A线程阻塞,B线程会一直等待,不能够响应中断;Lock可以尝试获得锁,线程可以不用一直等待,通过interrupt()方法能够响应中断(interrupt无法中断已经获取的锁,只能中断等待状态)
4.synchronized无法判断锁的状态;Lock可以知道有没有成功获取锁(可以通过其中的tryLock()等自带的多个方法去尝试获取锁)在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当多线程竞争资源非常激烈时,此时Lock的性能要远远优于synchronized。具体使用时要根据适当情况选择。
案例一
方法一 继承Thread类
package sell;import java.lang.Thread;public class SaleSysTest {public static void main(String[] args) {//创建5个线程,传入线程名[001]、[002]...并开启for(int i=1;i<6;i++) {new SaleThread("[00"+i+"]").start();}}}class SaleThread extends Thread{//车票数被共享,所以定义为static,数量为50.private static int ticket=50;//通过锁来保证线程不会重复访问private static Object obj=new Object();//有参构造传入线程名public SaleThread(String name) {// TODO Auto-generated constructor stubsuper(name);}//无参构造传入线程名public SaleThread() {}//重写run()方法,将售票动作放入其中public void run() {while(true) {//在锁外使用sleep(),以便于更好的解决复现问题try {Thread.sleep(100);}catch(InterruptedException e) {e.printStackTrace();}//使用synchronized需要锁统一资源,不然没效果,所以将obj初始化为static静态。//但让也可以使用字符串 synchronized("lock");lock随便输入synchronized(obj) {//还有余票---出票if(ticket>0) {System.out.println(Thread.currentThread().getName()+"号窗口第"+ticket+"票 正在出票...");ticket--;}else {//车票售罄System.out.println("车票已售罄,下次请趁早...");//退出System.exit(0);}}}}
}
方法二 实现Runnable接口
package sell;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;class Selldemolist implements Runnable {Scanner in=new Scanner(System.in);int tickets=in.nextInt();private int salenum=0;public void sellTickets() { synchronized (this) {if (tickets > 0) {tickets--;salenum++;System.out.println(Thread.currentThread().getName() + "已经购买编号为"+salenum+"的票");Date date=new Date();SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String time=sdf.format(date);System.out.println("出票时间为:"+time);try {Thread.sleep(500);} catch (InterruptedException e) { e.printStackTrace();}System.out.println("___________________________________");System.out.println(" ");}}}public void run() {while (tickets > 0) {sellTickets();try {Thread.sleep(400);if(tickets==0){System.out.println("非常抱歉,售票已经结束,请明天再来!");System.exit(-1);}} catch (InterruptedException e) {e.printStackTrace();}}}}public class Selldemo1 {public static void main(String[] args) {Selldemolist ticket=new Selldemolist();Thread mary = new Thread(ticket,"玛丽");Thread jack = new Thread(ticket,"杰克");Thread rose=new Thread(ticket,"柔丝");Thread black=new Thread(ticket,"布莱克");mary.start();jack.start();rose.start();black.start();}
}
案例二
方法一 继承Thread类
package Demo;public class Sellticket1 {public static void main(String[] args) {//创建3个线程,并开启for(int i=1;i<4;i++){new TicketWindow("窗口"+i+":").start();}}
}//方法1.继承Thread类
class TicketWindow extends Thread{private static int ticket = 100;//车票数被共享,所以定义为static private static Object obj = new Object();//通过锁来保证线程不会重复访问//有参构造传入线程名public TicketWindow(String name) {super(name);}public TicketWindow() {}//重写run()方法,将售票动作放入其中public void run() {while (true) {//在锁外使用sleep( );以便于更好的解决复现问题try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//也可以使用字符串 synchronized("lock");lock随便输入synchronized (obj) { if (ticket > 0) {System.out.println(Thread.currentThread().getName() + "第-- "+ ticket + " --票正在出票...");ticket--;} else { System.out.println("票已售完 下次再见!!");System.exit(0);}}}}
}
方法二 实现Runnable接口
package Demo;public class Sellticket2 {public static void main(String[] args) {Windows sc = new Windows();//创建3个线程,并开启for(int i=1;i<4;i++){new Thread(sc,"窗口"+i).start();}}
}//方法2.实现Runnable接口
class Windows implements Runnable{private int ticket = 100; private Object obj = new Object(); //定义一个线程同步对象public void run() { while(true){try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}//同步锁synchronized(obj){if(ticket > 0){System.out.println(Thread.currentThread().getName()+" 售出第-- "+ticket +" --张票");ticket--;}else{System.out.println("票已售完 下次再见!!");System.exit(0);}}} }
}
案例三
方法一 继承Thread类
package xiancheng;import java.util.Scanner;class thread extends Thread {public static int num, num1;public static Object obj = new Object();public int i = 1;public thread(String name) {super(name);}public thread() {}@Overridepublic void run() {// TODO 自动生成的方法存根while(true) {try {Thread.sleep(500);} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.printStackTrace();}synchronized(obj) {if(num > 0) {System.out.println("售票点:" + Thread.currentThread().getName() + " 当前卖出票号:" + (num1 - num + 1) );num--;} else {System.out.println("已卖完");System.exit(0);}}}}public void getChePiao(int chePiao) {num = chePiao; num1 = chePiao;}
}public class DoThread {public static void main(String[] args) {// TODO 自动生成的方法存根int i;Scanner scanner = new Scanner(System.in);System.out.print("请问要卖多少张票:");new thread().getChePiao(scanner.nextInt());for(i = 1 ; i <= 4 ; i++) {new thread("" + i).start();}}}
方法二 实现Runnable接口
package xiancheng;import java.util.Scanner;class Runn implements Runnable {public int num, i = 1, num1;@Overridepublic void run() {// TODO 自动生成的方法存根while(true) {try {Thread.sleep(500);} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.printStackTrace();}doRun();if(num <= 0) {System.exit(0);;}}}public synchronized void doRun() {if(i > 0 && i <= num1) {System.out.println("售票点:" + Thread.currentThread().getName() + " 当前卖出票号:" + i);i++;num--;} else if(num <= 0) {System.out.println("已卖完");System.exit(0);}}public void getChePiao() {Scanner scanner = new Scanner(System.in);System.out.print("请问要卖多少张票:");num = scanner.nextInt(); num1 = num;}
}public class DoRunnable {public static void main(String[] args) {// TODO 自动生成的方法存根int i;Runn runn = new Runn();runn.getChePiao();for(i = 1 ; i <= 4 ; i++) {new Thread(runn, "" + i).start();}}
}
案例四
方法一 继承Thread类
package one;import java.util.Scanner;public class Sale {private static int ticket,temp;public static void main(String [] args) {System.out.println("请输入您发放的票数:");Scanner in = new Scanner(System.in);String x = in.nextLine();ticket = Integer.parseInt(x);temp = ticket; for(int i=1;i<6;i++) {new sell1(" ["+i+"]",temp).start();}}
}class sell1 extends Thread { private static int ticket,temp1;private static Object obj = new Object();public sell1() {}public sell1(String name,int temp) {super (name);ticket = temp;}@Overridepublic void run() {temp1 = ticket;while (true) {try {Thread.sleep(100);}catch(InterruptedException e) {e.printStackTrace();}synchronized (obj) {if(ticket>0) {int a = temp1-ticket+1;System.out.println("售票点:"+Thread.currentThread().getName()+ "\t当前票号: "+a);ticket--;}else {System.out.println("车票已经售完,下次请趁早...");System.exit(0);}}}}
}
方法二 实现Runnable接口
package two;import java.util.Scanner;public class Sale2 {public static void main(String [] args) {int ticket1;System.out.println("请输入您发放的票数:");Scanner in = new Scanner(System.in);String x = in.nextLine();ticket1 = Integer.parseInt(x);sell s = new sell(ticket1); for(int i=1;i<6;i++) {new Thread(s,"["+i+"]").start();}}
}class sell implements Runnable{ private static int ticket,temp1;private static Object obj = new Object();public sell() {}public sell(int ticket1) {ticket = ticket1;}@Overridepublic void run() {temp1 = ticket; while (true) {try {Thread.sleep(100);}catch(InterruptedException e) {e.printStackTrace();}synchronized (obj) {if(ticket>0) {int a = temp1-ticket+1;System.out.println("售票点:"+Thread.currentThread().getName()+ "\t当前票号: "+a);ticket--;}else {System.out.println("车票已经售完,下次请趁早...");System.exit(0);}}}}
}
案例五
方法一 继承Thread类
package eclipse;public class Ticket1 {public static void main(String[] args) {// TODO Auto-generated method stub//首先创建5个线程,传入线程名:如[001]、[002]等,并将其开启。int i;for(i=1;i<+5;i++) {new SaleThread("[00"+i+"]").start();}}}
class SaleThread extends Thread{//由于车票数要对公众共享,所以要定义为静态成员变量,数量定为100.private static int ticket=100;//通过锁来保证线程都不会被重复访问.private static Object obj=new Object();//把有参构造传入线程名public SaleThread(String name) {super(name);}public SaleThread(){}//重新写入run()方法,将售票动作放入其中;
@Override
public void run() {while(true) {//要在锁外使用sleep();
try {Thread.sleep(100);}catch(InterruptedException e) {e.printStackTrace();}//使用synchronized需要统一资源,不然没效果,所以将obj初始化为static静态.//但让也可以使用字符串 synchronized("lock");lock随便输入
synchronized(obj) {//还有余票——————出票if(ticket>0) {System.out.println(Thread.currentThread().getName()+"号窗口正在出票...票号:"+ticket);ticket--;}else {//利用if,else语句来看看车票售出的情况,如果售出完成,则执行else下面的语句。System.out.println("车票已经售完,下次请趁早买票!");System.exit(0);}
}
}
}
}
方法二 实现Runnable接口
package eclipse;public class Ticket2 {public static void main(String[] args) {// TODO Auto-generated method stub
//首先得到对象SaleSys a =new SaleSys();//然后把对象放入线程中for(int i=1;i<6;i++) {new Thread(a,"[00"+i+"]").start();}}}class SaleSys implements Runnable{//定义票的总数private int ticket = 100;//定义一个线程同步的对象private Object obj=new Object();@Overridepublic void run() {while(true) {try {Thread.sleep(50);}catch(InterruptedException e) {e.printStackTrace();}//同步锁synchronized(obj) {if(ticket>0) {System.out.println(Thread.currentThread().getName()+"号窗口正在售票...票号:"+ticket);ticket--;}else {System.out.println("票已售完,请下次再来吧!");System.exit(0);}}}}
}
案例六
方法一 继承Thread类
package com.hym.Threaded;public class Sale_Thread{public static void main(String[] args) {// TODO Auto-generated method stub//创建五个窗口(线程)for(int i = 1;i < 6;i++) {new SaleThread("[0" + i + "]").start();}}
}
class SaleThread extends Thread{//车票数为共享变量,静态变量定义用static,数量为100private static int tickets = 100;//通过锁使这个线程不会被重复访问private static Object obj = new Object();public SaleThread(String name) {super(name);}public SaleThread() {}//重写run方法
@Override
public void run() {while(true) {try {Thread.sleep(200);}catch(InterruptedException e){e.printStackTrace();}//将obj初始化为static静态synchronized (obj) {if(tickets > 0) {System.out.println(Thread.currentThread().getName() + "号窗口第" + tickets-- + "票正在出票...");}else {//车票售完System.out.println("车票已售罄。");System.exit(0);}}}
}}
方法二 实现Runnable接口
package com.hym.Threaded;public class Test2 {public static void main(String[] args) {// TODO Auto-generated method stubSaleSys s = new SaleSys();//创建五个窗口(线程)for(int i = 1;i < 6;i++) {new SaleThread("[0" + i + "]").start();}}}
class SaleSys implements Runnable{//车票数为共享变量,静态变量定义用static,数量为100private static int tickets = 100;//通过锁使这个线程不会被重复访问private static Object obj = new Object();@Overridepublic void run() {// TODO Auto-generated method stubwhile(true) {try {Thread.sleep(200);}catch(InterruptedException e){e.printStackTrace();}//将obj初始化为static静态synchronized (obj) {if(tickets > 0) {System.out.println(Thread.currentThread().getName() + "号窗口第" + tickets-- + "票正在出票...");}else {//车票售完System.out.println("车票已售罄。");System.exit(0);}}}}
}
案例七
方法一 继承Thread类
package 售票;public class duo2 {public static void main(String[] args) {for(int i=1; i<4; i++){chuangkou2 sp = new chuangkou2();sp.setName(i+"号窗口");sp.start();}}}
class chuangkou2 extends Thread{private int tickets = 10;//车票总量public void run(){while(true){if(tickets>0){System.out.println(Thread.currentThread().getName() + "准备售票"); tickets--; System.out.println(Thread.currentThread().getName() + "卖出一张,剩余票数:" + tickets + "张");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}else{System.out.println(Thread.currentThread().getName() + "余票不足,停止售票!");break;}}}
}
方法二 实现Runnable接口
package 售票;public class duo{public static void main(String[] args) {chuangkou sp = new chuangkou();for(int i=1; i<4; i++){Thread t = new Thread(sp, i +"号窗口");t.start();}
}}
class chuangkou implements Runnable{private int tickets = 10;public void run(){while(true){if(tickets>0){shoupiao();}else{System.out.println(Thread.currentThread().getName() + "余票不足,停止售票!");break;}}}public synchronized void shoupiao(){if(tickets>0){System.out.println(Thread.currentThread().getName() + "准备售票"); tickets--; System.out.println(Thread.currentThread().getName() + "卖出一张,剩余票数:" + tickets + "张");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}
}
案例八
方法一 继承Thread类
package Thread;import java.util.Calendar;import javax.xml.crypto.Data;import java.util.*;
class sale_Thread extends Thread
{private static volatile int tickets=2000;public synchronized void run(){while(tickets>0){use();}}private synchronized static void use(){if(tickets>0){System.out.println(Thread.currentThread().getName() +"售出第"+tickets--+"张票");}
// try {
// Thread.sleep(200);
// } catch (InterruptedException e) {
// // TODO 自动生成的 catch 块
// e.printStackTrace();
// }}public static String getWeekOfDate(Date date) { String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; Calendar cal = Calendar.getInstance(); cal.setTime(date); int w = cal.get(Calendar.DAY_OF_WEEK) - 1; if (w < 0) w = 0; return weekDays[w]; }public static void main(String[] args) {Date date=new Date();String w=getWeekOfDate(date);System.out.println(w);String u1="星期五",u2="星期六";if(w.equals(u1)||w.equals(u2)){System.out.println("双休日期间,不予办理业务");}else{sale_Thread s1=new sale_Thread();sale_Thread s2=new sale_Thread();sale_Thread s3=new sale_Thread();sale_Thread s4=new sale_Thread();sale_Thread s5=new sale_Thread();Thread t1=new Thread(s1,"售票窗口1");Thread t2=new Thread(s2,"售票窗口2");Thread t3=new Thread(s3,"售票窗口3");Thread t4=new Thread(s4,"售票窗口4");Thread t5=new Thread(s5,"售票窗口5");t1.start();t2.start();t3.start();t4.start();t5.start();}}
}
方法二 实现Runnable接口
package Runable;public class 售票系统2
{public static int tickets=1000;protected synchronized static void use(){if(tickets>0){System.out.println(Thread.currentThread().getName() +"售出第"+tickets--+"张票");}
// try {
// Thread.sleep(200);
// } catch (InterruptedException e) {
// // TODO 自动生成的 catch 块
// e.printStackTrace();
// }}public static void main(String[] args) {Runner1 runner1 = new Runner1(); Runner2 runner2 = new Runner2(); Runner3 runner3 = new Runner3(); Thread thread1 = new Thread(runner1,"售票窗口1"); Thread thread2 = new Thread(runner2,"售票窗口2"); Thread thread3 = new Thread(runner3,"售票窗口3"); thread1.start(); thread2.start(); thread3.start();}
}
class Runner1 extends 售票系统2 implements Runnable { public void run() { while(tickets>0)use();}
} class Runner2 extends 售票系统2 implements Runnable { // 实现了Runnable接口,jdk就知道这个类是一个线程 public void run() {while(tickets>0)use();}
}class Runner3 extends 售票系统2 implements Runnable { // 实现了Runnable接口,jdk就知道这个类是一个线程 public void run() { while(tickets>0)use();}
}
案例九
方法一 继承Thread类
package Thticket;
/** 继承Thread类方法售票*/
public class MyThread {public static void main(String[] args) {System.out.println("我是实现系统一");for(int i=1;i<6;i++) {new saleMyThread("第"+i+"窗口 ").start();}}
}class saleMyThread extends Thread{private static int tic=100;//创建锁private static Object obj = new Object();//有参构造传入线程名public saleMyThread(String name) {super(name);}public saleMyThread() {}@Overridepublic void run() {// TODO Auto-generated method stubwhile (true) {try {//0.1秒Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//同步锁synchronized (obj) {if (tic > 0) {System.out.println(Thread.currentThread().getName() + "售出第"+ tic + "票");tic--;}else {//车票售完System.out.println("车票已售完,下次请趁早...");System.exit(0);}}}}}
方法二 实现Runnable接口
package Runticket;
/** 实现Runnable接口来售票*/
public class MyRunnable {public static void main(String[] args) {System.out.println("我是实现系统二");//得到对象saleMyRunnable mr=new saleMyRunnable();for(int i=1;i<6;i++){new Thread(mr,"第"+i+"窗口 ").start();}}
}
class saleMyRunnable implements Runnable{//定义票的总数private int tic = 100;//定义一个线程同步对象private Object obj = new Object();@Overridepublic void run() {// TODO Auto-generated method stubwhile(true) {try {//0.1秒Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//同步锁synchronized(obj) {if(tic > 0){System.out.println(Thread.currentThread().getName()+" 售出第 "+tic +" 张票");tic--;}else{System.out.println("票已售完,请下次再来!");System.exit(0);}}}}}