無標(biāo)題文章

一脓豪、 java基礎(chǔ)

1. java多線程基礎(chǔ)

1) 多線程的創(chuàng)建方式

1.多線程創(chuàng)建方式1

packagecom.qyl.springboot.controller;

/**

* 多線程的創(chuàng)建

* ? ? 方式一: 繼承與Thread類

* ? ? 1.創(chuàng)建一個(gè)子類類繼承Thread

* ? ? 2.在子類中重寫Thread的run()方法(線程要做的事寫到run()方法中)

* ? ? 3.創(chuàng)建該子類的對(duì)象 (在主線程里面創(chuàng)建)

* ? ? 4.通過此對(duì)象調(diào)用start方法

* ? ? 例子 : 遍歷100以內(nèi)的所有的偶數(shù)

*/

// 1.創(chuàng)建一個(gè)子類類繼承Thread

classMyThreadextendsThread{

//2.在子類中重寫Thread的run()方法 ? 線程要做的事寫到run()方法中

@Override

publicvoidrun() {

for(inti=0;i<100;i++) {

if(i%2==0){

System.out.println(i+"---"+Thread.currentThread().getName());

? ? ? ? ?? }

? ? ?? }

?? }

};

publicclassThreadTest{

publicstaticvoidmain(String[]args) {

// 3.創(chuàng)建該子類的對(duì)象

//主線程執(zhí)行

MyThreadmyThread=newMyThread();

MyThreadmyThread1=newMyThread();

//4.通過此對(duì)象調(diào)用start方法

//創(chuàng)建出來的線程執(zhí)行

/**

* 用start()方法啟動(dòng)? run()啟動(dòng)不了多線程效果

*/

myThread.start();

myThread1.start();//鄉(xiāng)啟動(dòng)多個(gè)就多創(chuàng)建對(duì)象即可

for(inti=0;i<100;i++) {

if(i%2==0){

System.out.println(i+" ++++++++++++++-"+Thread.currentThread().getName());

? ? ? ? ?? }

? ? ?? }

? ? ? ? //這種方法也可以 ? 匿名子類

System.out.println("http://///////////////");

newThread(){

@Override

publicvoidrun() {

for(inti=0;i<100;i++) {

if(i%2!=0){

System.out.println(Thread.currentThread().getName()+"http:////////////////"+i);

? ? ? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? }

? ? ? ? ?? }

}.start();

?? }

}

輸出結(jié)果:

48---Thread-0

78---Thread-1

50---Thread-0

18 ++++++++++++++-main

52---Thread-0

80---Thread-1

82---Thread-1

84---Thread-1

2. 多線程創(chuàng)建方式2

實(shí)現(xiàn)Runnable接口

1.創(chuàng)建一個(gè)實(shí)現(xiàn)了Run那邊了接口的類

2.實(shí)現(xiàn)類去實(shí)現(xiàn)Runable中的抽象方法

3.創(chuàng)建實(shí)現(xiàn)類的對(duì)象

4.將此對(duì)象作為參數(shù)傳遞到Thread類的構(gòu)造器中饶唤,創(chuàng)建Thread類的對(duì)象

5.通過Thread類的對(duì)象調(diào)用start()方法

packagecom.qyl.springboot.controller;

/**

* ###? 2)? 多線程創(chuàng)建方式2

*

* 實(shí)現(xiàn)Runnable接口

*

* 1.創(chuàng)建一個(gè)實(shí)現(xiàn)了Run那邊了接口的類

* 2.實(shí)現(xiàn)類去實(shí)現(xiàn)Runable中的抽象方法

* 3.創(chuàng)建實(shí)現(xiàn)類的對(duì)象

* 4.將此對(duì)象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對(duì)象

* 5.通過Thread類的對(duì)象調(diào)用start()方法

*/

//1.創(chuàng)建一個(gè)實(shí)現(xiàn)了Run那邊了接口的類

classMyRunnableimplementsRunnable{

//2.實(shí)現(xiàn)類去實(shí)現(xiàn)Runable中的抽象方法

@Override

publicvoidrun() {

for(inti=0;i<100;i++) {

if(i%2==0){

System.out.println(""+i+" ++++++++++++++-"+Thread.currentThread().getName());

? ? ? ? ?? }

? ? ?? }

?? }

}

publicclassRunableTest{

publicstaticvoidmain(String[]args) {

//3.創(chuàng)建實(shí)現(xiàn)類的對(duì)象

MyRunnablem1=newMyRunnable();

//4.將此對(duì)象作為參數(shù)傳遞到Thread類的構(gòu)造器中双抽,創(chuàng)建Thread類的對(duì)象

Threadthread=newThread(m1);

thread.setName("liudeh");

thread.start();

Threadt2=newThread(m1);

t2.setName("liudsssssssssseh");

t2.start();

?? }

}

2.線程生命周期

創(chuàng)建 調(diào)用start()

就緒 sleep()時(shí)間到,join()結(jié)束,獲取同步鎖,notify()/notifyALL(),resume()

阻塞 失去cpu執(zhí)行權(quán),或者yield()

運(yùn)行 sleep(),join(),等待同步鎖,wait(),suspend()

死亡 執(zhí)行完run(),調(diào)用stop(),出現(xiàn)Error/Exception且沒處理

3.線程同步

1.同步代碼塊

/**

* 線程同步與安全

* 處理共享數(shù)據(jù)的時(shí)候會(huì)出現(xiàn)線程安全問題

* 加鎖解決

* 4.在java中,通過同步機(jī)制來解決線程安全問題

* 方式一: 同步代碼塊

*? synchronized (同步監(jiān)視器){

* ? ?? //需要被同步的代碼 (吃操作共享數(shù)據(jù)的代碼就是需要被同步的代碼)

*}

*? 說明: ?1.(吃操作共享數(shù)據(jù)的代碼就是需要被同步的代碼)

* ? ? ?? 2.同步監(jiān)視器就是 鎖 任何類的對(duì)象都能充當(dāng)鎖

* ? ? ? ?? 鎖的要求: 多個(gè)線程供用同一把鎖

* ? ? ? ?? 哪怕你用一個(gè)狗 dag對(duì)象都可以

* 方式二: 同步方法

*

*

* 5.同步的方式雖然解決了線程安全

*? 缺點(diǎn)是同步代碼塊里面是單線程

*/

packagecom.qyl.java;

/**

* 開發(fā)一個(gè)類 實(shí)現(xiàn)Runnable 并重寫 run() 方法

*/

classWindowimplementsRunnable{

privateinttitck=100;

Objectobject=newObject();

@Override

publicvoidrun() {

while(true){

//同步代碼塊

synchronized(object){

if(titck>0){

System.out.println(Thread.currentThread().getName()+" 賣票-----票號(hào)碼為: "+titck);

titck--;

}else{

break;

? ? ? ? ? ?? }

? ? ? ?? }

? ?? }

?? }

}

/**

* 線程同步與安全

* 處理共享數(shù)據(jù)的時(shí)候會(huì)出現(xiàn)線程安全問題

* 加鎖解決

* 4.在java中,通過同步機(jī)制來解決線程安全問題

* 方式一 : 同步代碼塊

*? synchronized (同步監(jiān)視器) {

* ? ?? //需要被同步的代碼 (吃操作共享數(shù)據(jù)的代碼就是需要被同步的代碼)

*? }

*? 說明:? 1.(吃操作共享數(shù)據(jù)的代碼就是需要被同步的代碼)

* ? ? ?? 2.同步監(jiān)視器就是 鎖 任何類的對(duì)象都能充當(dāng)鎖

* ? ? ? ?? 鎖的要求 : 多個(gè)線程供用同一把鎖

* ? ? ? ?? 哪怕你用一個(gè)狗 dag對(duì)象都可以

* 方式二 : 同步方法

*

*

* 5.同步的方式雖然解決了線程安全

*? 缺點(diǎn)是同步代碼塊里面是單線程

*/

publicclassSyncThread{

publicstaticvoidmain(String[]args) {

Windowm1=newWindow();

Threadt1=newThread(m1);

Threadt2=newThread(m1);

Threadt3=newThread(m1);

t1.setName("窗口1");

t2.setName("窗口2");

t3.setName("窗口3");

t1.start();

t2.start();

t3.start();

?? }

}

注意:implement Runnable 的時(shí)候 this(當(dāng)前對(duì)象 ) 就可以當(dāng)做鎖? extends Threads的時(shí)候 不行

2.同步方法

// 1.一種情況可以直接把run改為同步的,但是要注意場(chǎng)景

classWindowimplementsRunnable{

privateinttitck=100;

Objectobject=newObject();

@Override

publicsynchronizedvoidrun() {

while(true){

//同步代碼塊

synchronized(this){

if(titck>0){

System.out.println(Thread.currentThread().getName()+" 賣票-----票號(hào)碼為: "+titck);

titck--;

}else{

break;

? ? ? ? ? ?? }

? ? ? ?? }

? ?? }

?? }

}

1.同步方法解決Runnable

packagecom.qyl.java;

/**

* 開發(fā)一個(gè)類 實(shí)現(xiàn)Runnable 并重寫 run() 方法

*/

classWindowimplementsRunnable{

privateinttitck=100;

Objectobject=newObject();

@Override

publicvoidrun() {

while(true){

sync();

? ?? }

?? }

privatesynchronizedvoidsync(){//同步監(jiān)視器就是this

//同步代碼塊

if(titck>0){

try{

Thread.sleep(10);

}catch(InterruptedExceptione) {

e.printStackTrace();

? ? ? ? ? ? ?? }

System.out.println(Thread.currentThread().getName()+" 賣票-----票號(hào)碼為: "+titck);

titck--;

? ? ? ? ?? }

?? }

}

/**

* 線程同步與安全

* 處理共享數(shù)據(jù)的時(shí)候會(huì)出現(xiàn)線程安全問題

* 加鎖解決

* 4.在java中,通過同步機(jī)制來解決線程安全問題

* 方式一 : 同步代碼塊

*? synchronized (同步監(jiān)視器) {

* ? ?? //需要被同步的代碼 (吃操作共享數(shù)據(jù)的代碼就是需要被同步的代碼)

*? }

*? 說明:? 1.(吃操作共享數(shù)據(jù)的代碼就是需要被同步的代碼)

* ? ? ?? 2.同步監(jiān)視器就是 鎖 任何類的對(duì)象都能充當(dāng)鎖

* ? ? ? ?? 鎖的要求 : 多個(gè)線程供用同一把鎖

* ? ? ? ?? 哪怕你用一個(gè)狗 dag對(duì)象都可以

* 方式二 : 同步方法

* ? ? 如果操作共享數(shù)據(jù)的代碼完整的在一個(gè)方法中,我們可以將該方法做成同步的

* ? ? 1.一種情況可以直接把run改為同步的,但是要注意場(chǎng)景

*

* 5.同步的方式雖然解決了線程安全

*? 缺點(diǎn)是同步代碼塊里面是單線程

*/

publicclassSyncThread{

publicstaticvoidmain(String[]args) {

Windowm1=newWindow();

Threadt1=newThread(m1);

Threadt2=newThread(m1);

Threadt3=newThread(m1);

t1.setName("窗口1");

t2.setName("窗口2");

t3.setName("窗口3");

t1.start();

t2.start();

t3.start();

?? }

}

2.同步方法解決thread

packagecom.qyl.java;

classWindowsextendsThread{

privatestaticinttickets=100;

privatestaticObjectobject=newObject();

@Override

publicvoidrun() {

while(true) {

//同步代碼塊

show();

? ? ?? }

?? }

privatestaticsynchronizedvoidshow(){//加個(gè)static 就可以了

if(tickets>0) {

try{

sleep(10);

}catch(InterruptedExceptione) {

e.printStackTrace();

? ? ?? }

System.out.println(Thread.currentThread().getName()+" 賣票-----票號(hào)碼為: "+tickets);

tickets--;

?? }

}

}

publicclassextendsThread{

publicstaticvoidmain(String[]args) {

Windowsw1=newWindows();

Windowsw2=newWindows();

Windowsw3=newWindows();

w1.setName("窗口1");

w2.setName("窗口2");

w3.setName("窗口3");

w1.start();

w2.start();

w3.start();

?? }

}

4.Thread 的常用方法介紹:

1) start():

啟動(dòng)當(dāng)前線程莺掠,調(diào)用當(dāng)前線程的run()方法 。

2) run():

通常是重寫Thread 的run()方法 將線程要做的事情聲明在該方法中

3) currentThread() :

Thread 的靜態(tài)方法 獲取到當(dāng)前線程

4)getName() setName():

給線程名字的方法

package com.qyl.springboot.controller;

class MyThread1 extends Thread{

@Override

public void run() {

for (int i = 0; i < 100; i++) {

if(i % 2 == 0 ){

try {

sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

//Thread.currentThread().setName("lalala"); 線程命名 方式1

System.out.println(Thread.currentThread().getName()+"*******"+i);

}

}

}

}

public class ThreadTest1 {

public static void main(String[] args) {

MyThread1 myThread1 = new MyThread1();

//線程命名 方式2

myThread1.setName("huren");

myThread1.start();

//給主線程命名

Thread.currentThread().setName("zongguanjun");

for (int i = 0; i < 100; i++) {

if(i % 2 == 0 ){

//Thread.currentThread().setName("lalala"); 線程命名

System.out.println(Thread.currentThread().getName()+"*******///////////"+i);

}

}

}

}

------------------------通過構(gòu)造器命名線程

package com.qyl.springboot.controller;

class MyThread1 extends Thread{

@Override

public void run() {

for (int i = 0; i < 100; i++) {

if(i % 2 == 0 ){

//Thread.currentThread().setName("lalala"); 線程命名 方式1

System.out.println(Thread.currentThread().getName()+"*******"+i);

}

if(i % 20 == 0){

yield();

}

}

}

//線程命名方式3? 通過構(gòu)造器命名

public MyThread1(String name){

super(name);

}

}

public class ThreadTest1 {

public static void main(String[] args) {

MyThread1 myThread1 = new MyThread1("sssssss");

//線程命名 方式2

myThread1.setName("huren");

myThread1.start();

//給主線程命名

Thread.currentThread().setName("zongguanjun");

for (int i = 0; i < 100; i++) {

if(i % 2 == 0 ){

//Thread.currentThread().setName("lalala"); 線程命名

System.out.println(Thread.currentThread().getName()+"*******///////////"+i);

}

}

}

}

5)yiel ():

釋放當(dāng)前cpu的執(zhí)行權(quán)

6)join ():

在線程a中調(diào)用線程b的join()方法闯冷,此時(shí)線程a進(jìn)入阻塞狀態(tài)砂心,等b執(zhí)行完之后,a結(jié)束阻塞繼續(xù)執(zhí)行

7) stop():

強(qiáng)制結(jié)束該線程蛇耀,不推薦使用

8) sleep(lang millitime):

當(dāng)前線程睡眠指定的一段時(shí)間

9) isAlive()

判斷當(dāng)前線程是否存活

10)property()get辩诞,set

線程的優(yōu)先級(jí) 1-10 默認(rèn)5

public void? newRunnableMethod () {

new Thread(new Runnable() {

@Override

public void run() {

// 存放所有openid

List openids = new ArrayList<>();

List usersGuid = new ArrayList<>();

SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);

Task_Info_News_ReadMapper mapper = sqlSession.getMapper(Task_Info_News_ReadMapper.class);

try{

// 組裝info_news_read 表所需要的數(shù)據(jù),并存入數(shù)據(jù)庫(kù)中

for(int i = 0; i< list.size();i++){

String strUserGuid =? (String)list.get(i).get("strUserGuid");

// 通過臨時(shí)存放usersGuid,去重(對(duì)根據(jù)范圍查出數(shù)據(jù)進(jìn)行去重)

if(!usersGuid.contains(strUserGuid)){

usersGuid.add(strUserGuid);

// 獲取openid

Object strOpenid = list.get(i).get("strOpenid");

// 如果openid不為空,則放入openids集合中(用來推送模板消息)

if(strOpenid != null){

openids.add(strOpenid.toString());

}

list.get(i).put("strGuid", UUID.randomUUID().toString());

list.get(i).put("strNewsGuid",info_News.getStrGuid());

list.get(i).put("strCreator",info_News.getStrCreator());

list.get(i).put("dtCreateTime", info_News.getDtCreateTime());

mapper.insertMap(list.get(i));

}

if(i % 1000 == 0 || i == list.size() - 1){

sqlSession.commit();

sqlSession.clearCache();

}

}

}catch (Exception e) {

logger.info("事物已回滾");

loggerErr.info("發(fā)布任務(wù)失敗 ==>" + e.getMessage());

sqlSession.rollback();

e.printStackTrace();

}finally {

sqlSession.close();

}

PropertiesUtils utils = null;

try {

utils = new PropertiesUtils("global/param_hexi.properties");

} catch (Exception e) {

logger.info("global/param_hexi.properties 文件找不到");

e.printStackTrace();

return;

}

// 微信模板消息,任務(wù)的模板id

if(openids.size() > 0){

String template_id = utils.getProperty("template_id");

sendNewsToWebchatUser(template_id, openids, info_News);

}

}

}).start();

}

//不同的寫法

package com.qyl.java;

/**

* 開發(fā)一個(gè)類 實(shí)現(xiàn)Runnable 并重寫 run() 方法

*/

class MyThreadRunnable implements Runnable{

@Override

public void run() {

for (int i = 0; i < 100; i++) {

if (i % 2 == 0){

System.out.println(Thread.currentThread().getName() + "=================" +i);

}

}

}

}

/**

* 線程同步與安全

*/

public class SyncThreadTest {

public static void main(String[] args) {

MyThreadRunnable m1 = new MyThreadRunnable();

Thread t1 = new Thread(m1);

t1.setName("子線程1");

t1.start();

new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 100; i++) {

if (i % 2 != 0){

Thread.currentThread().setName("主線程");

System.out.println(Thread.currentThread().getName() + "=================" +i);

}

}

}

}).start();

}

}

5.使用同步機(jī)制將單例模式中的懶漢式改寫為線程安全的

1.效率較低的方式

package com.qyl.java;

/**

* 使用同步機(jī)制將單例模式中的懶漢式改寫為線程安全的

*/

public class BankTest {

}

class Bank{

private Bank(){}

private static Bank instance = null;

public static? Bank getInstance(){ //加上synchronized就變成線程安全的了

synchronized () {

if (instance == null){

instance = new Bank();

}

return instance;

}

}

}

2.效率高點(diǎn)

package com.qyl.java;

/**

* 使用同步機(jī)制將單例模式中的懶漢式改寫為線程安全的

*/

public class BankTest {

}

class Bank{

private Bank(){

}

private static Bank instance = null;

public static? Bank getInstance(){ //加上synchronized就變成線程安全的了

if (instance == null) {

synchronized (Bank.class) {

if (instance == null) {

instance = new Bank();

}

}

}

return instance;

}

}

6.線程死鎖問題

1.死鎖案例

package com.qyl.java;

/**

* 演示死鎖問題

*/

public class SiSuo {

public static void main(String[] args) {

StringBuffer s1 = new StringBuffer();

StringBuffer s2 = new StringBuffer();

new Thread(){

@Override

public void run() {

synchronized (s1){

s1.append("a");

s2.append("1");

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (s2){

s1.append("b");

s2.append("2");

System.out.println(s1);

System.out.println(s2);

}

}

}

}.start();

new Thread(new Runnable() {

@Override

public void run() {

synchronized (s2){

s1.append("c");

s2.append("3");

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (s1){

s1.append("d");

s2.append("4");

System.out.println(s1);

System.out.println(s2);

}

}

}

}).start();

}

}

2.解決線程安全問題三 Lock鎖

Inspection '在使用阻塞等待獲取鎖的方式中纺涤,必須在try代碼塊之外译暂,并且在加鎖方法與try代碼塊之間沒有任何可能拋出異常的方法調(diào)用,避免加鎖成功后撩炊,在finally中無法解鎖外永。說明一:如果在lock方法與try代碼塊之間的方法調(diào)用拋出異常,那么無法解鎖拧咳,造成其它線程無法成功獲取鎖伯顶。說明二:如果lock方法在try代碼塊之內(nèi),可能由于其它方法拋出異常,導(dǎo)致在finally代碼塊中砾淌,unlock對(duì)未加鎖的對(duì)象解鎖啦撮,它會(huì)調(diào)用AQS的tryRelease方法(取決于具體實(shí)現(xiàn)類),拋出IllegalMonitorStateException異常汪厨。說明三:在Lock對(duì)象的lock方法實(shí)現(xiàn)中可能拋出unchecked異常赃春,產(chǎn)生的后果與說明二相同。' options

package com.qyl.java;

import java.util.concurrent.locks.ReentrantLock;

class WindowLock implements Runnable{

private int titck = 100;

//1.實(shí)例化一個(gè)lock

private ReentrantLock lock = new ReentrantLock();

@Override

public void run() {

while (true){

try {

lock.lock();

//2.調(diào)用lock()

if (titck> 0){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+" 賣票-----票號(hào)碼為: " + titck );

titck--;

} else {

break;

}

} finally {

//調(diào)用解鎖方法

lock.unlock();

}

}

}

}

public class LockTest {

public static void main(String[] args) {

WindowLock m1 = new WindowLock();

Thread t1 = new Thread(m1);

Thread t2 = new Thread(m1);

Thread t3 = new Thread(m1);

t1.setName("窗口1");

t2.setName("窗口2");

t3.setName("窗口3");

t1.start();

t2.start();

t3.start();

}

}

7.wait() notify()

1.兩個(gè)線程交叉打印100以內(nèi)的數(shù)

package com.qyl.springboot.controller;

//? ? 2個(gè)線程交叉打印100以內(nèi)的數(shù)字

class WaitNotify implements Runnable{

private int number = 1;

@Override

public void run() {

while (true){

synchronized (this) {

//喚醒全部線程

//notifyAll();

//喚醒線程

notify();

if (number<=100){

//睡眠 不釋放線程 不釋放鎖

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"? ---打印了 : "+number);

number++;

//等待? 但是釋放線程 釋放鎖

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}else {

break;

}

}

}

}

}

public class WaitNotifyTest {

public static void main(String[] args) {

WaitNotify w1 = new WaitNotify();

Thread t1 = new Thread(w1);

Thread t2 = new Thread(w1);

t1.setName("線程1 +++++: ");

t2.setName("線程2 -----: ");

t1.start();

t2.start();

}

}

2.wait()劫乱,notify()织中, notifyAll()

只能用在同步代碼塊或者方法中? lock不能用

并且調(diào)用者必須是同步監(jiān)視器

這三個(gè)方法是定義在對(duì)象Object中的 所以都可以用對(duì)象調(diào)

3.sleep() 和wait()區(qū)別

相同點(diǎn):都可以使得當(dāng)前線程進(jìn)入阻塞狀態(tài)

不同點(diǎn): 1) Thread類中聲明Sleep()? ,Object類中聲明Wait()

2) sleep()不會(huì)釋放鎖衷戈,wait() 會(huì)

3.)sleep ()在任何場(chǎng)景都可調(diào)用狭吼,wait只能在同步代碼中調(diào)用

8.測(cè)試題

1.存錢 ,兩個(gè)人 公用一個(gè)賬戶,各村三次 每次1000

方法一:

package com.qyl.springboot.controller;

/**

* 測(cè)試

* 存錢 ,兩個(gè)人 公用一個(gè)賬戶,各村三次 每次1000

* 1.多線程 : 兩個(gè)人

* 2.共享數(shù)據(jù) : 賬戶

* 所以有了線程安全問題

*/

public class AccountTest {

public static void main(String[] args) {

//定義初始化的賬戶

Account account = new Account(1000);

//聲明兩個(gè)對(duì)象 去開線程

Customer c1 = new Customer(account);

Customer c2 = new Customer(account);

c1.setName("甲");

c2.setName("乙");

c1.start();

c2.start();

}

}

/**

* 創(chuàng)建一個(gè)賬戶類

*/

class Account {

//聲明賬戶余額

private double balance;

//構(gòu)造器

public Account(double balance) {

this.balance = balance;

}

//往里面存錢的方法

//加synchronize 同步

public synchronized void cunQian (double atm){

if ((atm>0)){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("當(dāng)前余額: "+balance);

balance += atm;

System.out.println(Thread.currentThread().getName()+"? : 存了 "+atm+" 元,已到賬.當(dāng)前余額為"+balance+"員");

}

}

}

//用戶類,繼承Thread

class Customer extends Thread{

//注入 Account

private Account account;

//構(gòu)造器

public Customer(Account account) {

this.account = account;

}

//子類重寫父類Run方法

@Override

public void run() {

for (int i = 0; i < 3; i++) {

//調(diào)用存錢方法

account.cunQian(1000);

}

}

}

方法二:

package com.qyl.springboot.javaTest;

public class CustomerQyl extends Thread{

private AccountQyl accountQyl;

public CustomerQyl(AccountQyl accountQyl) {

this.accountQyl = accountQyl;

}

@Override

public? void run() {

for (int i = 0; i < 4; i++) {

String s =? accountQyl.Pay(1000);

System.out.println(Thread.currentThread().getName()+"? ***? "+s);

}

}

}

package com.qyl.springboot.javaTest;

public class AccountQyl {

private double balance;

public AccountQyl(double balance) {

this.balance = balance;

}

public synchronized String Pay (double atm){

if (atm>0){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("當(dāng)前余額: "+balance);

balance += atm;

System.out.println(Thread.currentThread().getName()+"? : 存了 "+atm+" 元,已到賬.當(dāng)前余額為"+balance+"員");

}

return "存錢成功";

}

}

package com.qyl.springboot.javaTest;

public class testSync {

public static void main(String[] args) {

AccountQyl accountQyl = new AccountQyl(300);

CustomerQyl c1 = new CustomerQyl(accountQyl);

CustomerQyl c2 = new CustomerQyl(accountQyl);

c1.setName("甲");

c2.setName("乙");

c1.start();

c2.start();

}

}

2.java? 遞歸

package com.esint.jm.wx_hxpublic.util;

//遞歸 漢諾塔

public class QylDiGuiTest {

static int times = 0;

public? static void? move (int num , char source , char dest){

System.out.println("第"+(++times)+"步驟? "+num +" 號(hào)盤子從 "+source+" 柱子到 "+dest+"柱子");

}

public static void hnt (int n,char source,char mid,char dest){

if (1 == n){

move(n,source,dest);

}else {

hnt(n-1,source,dest,mid);

move(n,source,dest);

hnt(n-1,mid,source,dest);

}

}

public static void main(String[] args) {

hnt(5,'A','B','C');

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市殖妇,隨后出現(xiàn)的幾起案子刁笙,更是在濱河造成了極大的恐慌,老刑警劉巖谦趣,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疲吸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡前鹅,警方通過查閱死者的電腦和手機(jī)摘悴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舰绘,“玉大人蹂喻,你說我怎么就攤上這事∥媸伲” “怎么了口四?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)者蠕。 經(jīng)常有香客問我窃祝,道長(zhǎng),這世上最難降的妖魔是什么踱侣? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任粪小,我火速辦了婚禮,結(jié)果婚禮上抡句,老公的妹妹穿的比我還像新娘探膊。我一直安慰自己,他們只是感情好待榔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布逞壁。 她就那樣靜靜地躺著流济,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腌闯。 梳的紋絲不亂的頭發(fā)上绳瘟,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音姿骏,去河邊找鬼糖声。 笑死,一個(gè)胖子當(dāng)著我的面吹牛分瘦,可吹牛的內(nèi)容都是我干的蘸泻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嘲玫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼悦施!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起去团,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤抡诞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后渗勘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沐绒,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俩莽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年旺坠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扮超。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡取刃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出出刷,到底是詐尸還是另有隱情璧疗,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布馁龟,位于F島的核電站崩侠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏坷檩。R本人自食惡果不足惜却音,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望矢炼。 院中可真熱鬧系瓢,春花似錦、人聲如沸句灌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至骗绕,卻和暖如春藐窄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酬土。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工枷邪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诺凡。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓东揣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親腹泌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嘶卧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • JAVA面試題 1、作用域public,private,protected,以及不寫時(shí)的區(qū)別答:區(qū)別如下:作用域 ...
    JA尐白閱讀 1,153評(píng)論 1 0
  • 概述 這篇文章中凉袱,我不會(huì)說多線程是什么芥吟、線程和進(jìn)程的區(qū)別、多線程有什么用专甩,當(dāng)然我也不會(huì)說什么是串行钟鸵、什么是并行等問...
    hashakey閱讀 300評(píng)論 0 0
  • Java的wait()、notify()學(xué)習(xí)三部曲由三篇文章組成涤躲,內(nèi)容分別是: 一棺耍、通過閱讀openjdk8的源碼...
    程序yuan閱讀 352評(píng)論 0 0
  • JavaWeb——Servlet Tomcat工作機(jī)制動(dòng)畫演示(點(diǎn)擊動(dòng)圖可全屏觀看) 什...
    NuvoleBian_8782閱讀 211評(píng)論 0 0
  • # GC和GC Tuning ### GC的基礎(chǔ)知識(shí) #### 1.什么是垃圾 > C語言申請(qǐng)內(nèi)存:malloc ...
    Avatar_7636閱讀 1,592評(píng)論 0 0