Skip to content

Commit 069af4d

Browse files
author
ymm
committed
Merge remote-tracking branch 'choose_remote_name/master'
2 parents b6d0683 + fc11bf1 commit 069af4d

8 files changed

Lines changed: 399 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.xiaoyang.itcast;
2+
3+
import java.util.concurrent.locks.Condition;
4+
import java.util.concurrent.locks.Lock;
5+
import java.util.concurrent.locks.ReentrantLock;
6+
/*作为一个示例,假定有一个绑定的缓冲区,它支持 put 和 take 方法。
7+
* 如果试图在空的缓冲区上执行 take 操作,则在某一个项变得可用之前,
8+
* 线程将一直阻塞;如果试图在满的缓冲区上执行 put 操作,
9+
* 则在有空间变得可用之前,线程将一直阻塞。
10+
* 我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,
11+
* 这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,
12+
* 一次只通知一个线程。可以使用两个 Condition 实例来做到这一点。
13+
* */
14+
15+
class BoundedBuffer {
16+
final Lock lock = new ReentrantLock();
17+
final Condition notFull = lock.newCondition();
18+
final Condition notEmpty = lock.newCondition();
19+
20+
final Object[] items = new Object[100];
21+
int putptr, takeptr, count;
22+
23+
public void put(Object x) throws InterruptedException {
24+
lock.lock();
25+
try {
26+
while (count == items.length)
27+
notFull.await();
28+
items[putptr] = x;
29+
if (++putptr == items.length) putptr = 0;
30+
++count;
31+
notEmpty.signal();
32+
} finally {
33+
lock.unlock();
34+
}
35+
}
36+
37+
public Object take() throws InterruptedException {
38+
lock.lock();
39+
try {
40+
while (count == 0)
41+
notEmpty.await();
42+
Object x = items[takeptr];
43+
if (++takeptr == items.length) takeptr = 0;
44+
--count;
45+
notFull.signal();
46+
return x;
47+
} finally {
48+
lock.unlock();
49+
}
50+
}
51+
}
52+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.xiaoyang.itcast;
2+
3+
import java.util.concurrent.ExecutorService;
4+
import java.util.concurrent.Executors;
5+
6+
public class ExxcutorsStudy {
7+
8+
public static void main(String[] args) {
9+
10+
ExecutorService threadPool = Executors.newFixedThreadPool(3);
11+
threadPool.execute(new Runnable() {
12+
@Override
13+
public void run() {
14+
for (int i = 1; i <= 10; i++) {
15+
System.out.println(Thread.currentThread().getName()
16+
+ " ÕýÔÚÖ´ÐеÚ"+i+"´ÎÑ­»·" +i);
17+
}
18+
}
19+
});
20+
}
21+
22+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.xiaoyang.itcast;
2+
3+
/*模拟往出卖火车票 4个窗口同时往外卖 有100张票*/
4+
public class ShareDate12306 {
5+
public static void main(String[] args) throws InterruptedException {
6+
ShearDate shearDate = new ShearDate();
7+
// 启动4个线程
8+
Thread thread1 = new Thread(shearDate);
9+
thread1.setName("售票员1");
10+
thread1.start();
11+
Thread.sleep(1);
12+
Thread thread2 = new Thread(shearDate);
13+
thread2.setName("售票员2");
14+
thread2.start();
15+
// Thread thread3 = new Thread(shearDate);
16+
// thread3.setName("售票员3");
17+
// thread3.start();
18+
// Thread thread4 = new Thread(shearDate);
19+
// thread4.setName("售票员4");
20+
// thread4.start();
21+
}
22+
23+
static class ShearDate implements Runnable{
24+
private boolean TickerEn = true;
25+
// 定义票的总数
26+
private int TickerCount = 100;
27+
@Override
28+
public void run() {
29+
while(TickerEn){
30+
System.out.println(Thread.currentThread().getName() +" 出票成功。 车票代码为--->"+TickerCount);
31+
TickerCount--;
32+
if(TickerCount <1){
33+
TickerEn = false;
34+
}
35+
}
36+
37+
}
38+
}
39+
40+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.xiaoyang.itcast;
2+
3+
4+
5+
public class Thread4Add4Jian {
6+
7+
// 4个线程 2个线程对i 进行+1 操作 另外两个线程对i进行-1操作
8+
/*分析一下
9+
* 两个对i 加1操作的线程需要互斥,我加的时候你不能加否则会出现计数不对
10+
* 同理 两个对i 减1操作的线程需要互斥,我减的时候你不能加否则会出现计数不对
11+
* 另外 加和减 之间的总体上也需要互斥,我在做加的时候你也不能做减法。
12+
*
13+
* */
14+
public static void main(String[] args) throws InterruptedException {
15+
final ShareDate myDate = new ShareDate();
16+
17+
new Thread(new MyRunnableAdd(myDate)).start();
18+
new Thread(new MyRunnableAdd(myDate)).start();
19+
new Thread(new MyRunnableDec(myDate)).start();
20+
new Thread(new MyRunnableDec(myDate)).start();
21+
///////////////////////////////////////////////////////////////
22+
/*new Thread(new Runnable() {
23+
@Override
24+
public void run() {
25+
myDate.decrement();
26+
}
27+
}).start();
28+
29+
new Thread(new Runnable() {
30+
@Override
31+
public void run() {
32+
myDate.increment();
33+
}
34+
}).start();*/
35+
///////////////////////////////////////////////////////////////
36+
37+
}
38+
39+
static class MyRunnableAdd implements Runnable{
40+
int i= 0;
41+
private ShareDate Date;
42+
public MyRunnableAdd(ShareDate Date1) {
43+
this.Date = Date1;
44+
}
45+
public void run() {
46+
// i = i+1;
47+
// Thread.currentThread().setName("--->"+(++i));
48+
Date.increment();
49+
}
50+
}
51+
52+
static class MyRunnableDec implements Runnable{
53+
private ShareDate Date;
54+
public MyRunnableDec(ShareDate Date1) {
55+
this.Date = Date1;
56+
}
57+
public void run() {
58+
// Thread.currentThread().setName("<---");
59+
Date.decrement();
60+
}
61+
}
62+
63+
64+
65+
static class ShareDate {
66+
private int j = 10;
67+
public synchronized void increment(){
68+
j++;
69+
System.out.println(Thread.currentThread().getName()+ " m:加1之后m:"+j +" "+ +System.currentTimeMillis());
70+
}
71+
72+
public synchronized void decrement(){
73+
j--;
74+
System.out.println(Thread.currentThread().getName()+ " m:减1之后m:"+j +" "+System.currentTimeMillis());
75+
}
76+
}
77+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.xiaoyang.itcast;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.Random;
6+
7+
8+
public class ThreadLocal {
9+
10+
// 创建一个静态变量,在主线程里面设置随机数,然后再子线程里面获取。
11+
private static int date = 0;
12+
private static Map<Thread, Integer> threadMap = new HashMap<Thread, Integer>();
13+
public static void main(String[] args) throws InterruptedException {
14+
15+
for(int i = 0;i<2;i++){
16+
new Thread(new Runnable() {
17+
@Override
18+
public void run() {
19+
Integer date = new Random().nextInt();
20+
threadMap.put(Thread.currentThread(),date);
21+
System.out.println("线程名"+Thread.currentThread().getName()+"设置date的值为"+date);
22+
new A().getDate();
23+
new B().getDate();
24+
}
25+
}).start();
26+
}
27+
}
28+
29+
static class A{
30+
public void getDate(){
31+
;
32+
System.out.println("A "+Thread.currentThread().getName()+"【获取 】date的值为"+threadMap.get(Thread.currentThread()));
33+
}
34+
}
35+
36+
static class B{
37+
public void getDate(){
38+
System.out.println("B "+Thread.currentThread().getName()+"【获取 】date的值为"+threadMap.get(Thread.currentThread()));
39+
}
40+
}
41+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.xiaoyang.itcast;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.Random;
6+
7+
public class ThreadScopeShareData {
8+
9+
private static int data = 0;
10+
private static Map<Thread, Integer> threadData = new HashMap<Thread, Integer>();
11+
public static void main(String[] args) {
12+
for(int i=0;i<2;i++){
13+
new Thread(new Runnable(){
14+
@Override
15+
public void run() {
16+
/*int*/ data = new Random().nextInt();
17+
System.out.println(Thread.currentThread().getName()
18+
+ " has put data :" + data);
19+
threadData.put(Thread.currentThread(), data);
20+
new A().get();
21+
new B().get();
22+
}
23+
}).start();
24+
}
25+
}
26+
27+
static class A{
28+
public void get(){
29+
int data = threadData.get(Thread.currentThread());
30+
System.out.println("A from " + Thread.currentThread().getName()
31+
+ " get data :" + data);
32+
}
33+
}
34+
35+
static class B{
36+
public void get(){
37+
int data = threadData.get(Thread.currentThread());
38+
System.out.println("B from " + Thread.currentThread().getName()
39+
+ " get data :" + data);
40+
}
41+
}
42+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.xiaoyang.itcast;
2+
3+
/*面试题 子线程输出1-10
4+
* 然后主线程输出1-50 然后子线程再输出依次循环累计50次
5+
* 实现思路
6+
* 1、首先程序本身运行 就是一个主线程 mian线程
7+
* 2、再创建一个线程作为子线程
8+
* 3、先在内部把50次外循环和各自10、50次内循环写好,此时的问题是他们会交叉输出。
9+
* 4、加上synchronized关键字 主线程 锁在本类的字节码上 把内循环锁上,保障每次循环的时候别的线程进入不了自己的循环。
10+
* 保障自己循环的完整性。
11+
* 5、创建一个单独的类,里面写两个输出的方法,一个是主线程、一个是子线程。方便加锁。同时也方便调度
12+
* 6、此时虽然能保证自己输出的时候别的线程进入不了但是自己的输出不能保证只是一次的输出。
13+
* 7、加入Flag判断,如果不该自己输出,自己wait() 等待唤醒。
14+
* 如果该自己输出,输出完以后,更改Flag的值,并且notify唤醒等待的线程。
15+
* 8、第7点的逻辑加在主线程 和子线程上面
16+
*
17+
* */
18+
public class ThreadSyn {
19+
20+
public static void main(String[] args) {
21+
final Buesiness buesiness = new Buesiness();
22+
// 子线程输出10
23+
new Thread(new Runnable() {
24+
@Override
25+
public void run() {
26+
for (int i = 1; i <= 50; i++) {
27+
buesiness.Main(i);
28+
}
29+
}
30+
}).start();
31+
32+
// 主线程输出50
33+
for (int i = 1; i <= 50; i++) {
34+
buesiness.Sub(i);
35+
}
36+
37+
}
38+
39+
static class Buesiness {
40+
boolean isRun = true;
41+
public synchronized void Main(int i) {
42+
while(isRun){
43+
try {
44+
this.wait();
45+
} catch (InterruptedException e) {
46+
e.printStackTrace();
47+
}
48+
}
49+
50+
for (int j = 1; j <= 50; j++) {
51+
System.out.println("Mian线程运行-->" + Thread.currentThread().getName() + " 内循环次数" + j + "外循环次数" + i);
52+
}
53+
isRun = true;
54+
this.notify();
55+
}
56+
57+
public synchronized void Sub(int i) {
58+
while(!isRun){
59+
try {
60+
this.wait();
61+
} catch (InterruptedException e) {
62+
e.printStackTrace();
63+
}
64+
}
65+
for (int j = 1; j <= 10; j++) {
66+
System.out.println("Sub线程运行-->" + Thread.currentThread().getName() + " 内循环次数" + j + "外循环次数" + i);
67+
}
68+
isRun = false;
69+
this.notify();
70+
}
71+
}
72+
73+
}

0 commit comments

Comments
 (0)