您的位置:首页 > 编程语言 > Java开发

javaSe 线程练习

2019-06-14 13:19 155 查看

1、编写两个线程,一个线程打印1-52的整数,另一个线程打印字母A-Z。打印顺序为12A34B56C….5152Z。即按照整数和字母的顺序从小到大打印,并且每打印两个整数后,打印一个字母,交替循环打印,直到打印到整数52和字母Z结束

[code]    @Test//junit测试
public void print()  {
Print p = new Print();
Thread t1 = new Thread(p);
t1.setName("线程1:");
Thread t2 = new Thread(p);
t2.setName("线程2:");

t1.start();
t2.start();
}

class Print implements Runnable{
int m=1;
@Override
public void run() {
while(true) {
synchronized(this) {
if(m>52) break;
notify();
if(m%2==0) {
System.out.println(Thread.currentThread().getName()+(char)(m/2+64));
m++;
}else {
System.out.println(Thread.currentThread().getName()+m+" "+ (m+1));
m++;
}

try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

}

2、有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池用一个数组int[] arr = {10,5,20,50,100,200,500,800,2,80,300}; 
        创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”,随机从arr数组中获取奖项元素并打印在控制台上,格式如下:
        抽奖箱1 又产生了一个 10 元大奖
        抽奖箱2 又产生了一个 100 元大奖

[code]public class Hhreades {
@Test
public void show() {
Jackpot j = new Jackpot();
Thread t1 = new Thread(j);
Thread t2 = new Thread(j);
t1.setName("抽奖箱1");
t2.setName("抽奖箱2");

t1.start();
t2.start();
}
}

//做法一:

class Jackpot implements Runnable{
int[] arr = {10,5,20,50,100,200,500,800,2,80,300};
List<Integer> list = new ArrayList<>();
@Override
public void run() {
Random ran = new Random();
int i=ran.nextInt(arr.length);
while(true) {
synchronized (this) {
while(list.contains(i)) {
i = ran.nextInt(arr.length);
}
System.out.println(Thread.currentThread().getName()+String.format("又产生了一个 %s 元大奖", arr[i]));
list.add(i);
}
}
}
}

//做法二:

class Jackpot1 implements Runnable{
int[] arr = {10,5,20,50,100,200,500,800,2,80,300};
List<Integer> list = new ArrayList<>();
{
for(int i=0;i<arr.length;i++) {
list.add(arr[i]);
}
}
@Override
public void run() {
Random ran = new Random();
int i;
while(true) {
synchronized (this) {
if(!list.isEmpty()) {
i = ran.nextInt(list.size());
System.out.println(Thread.currentThread().getName()+String.format("又产生了一个 %s 元大奖", list.get(i)));
list.remove(i);
}
}
}
}

}

3、某公司组织年会,会议入场时有两个入口,在入场时每位员工都能获取一张双色球彩票,假设公司有100个员工,利用多线程模拟年会入场过程,
并分别统计每个入口入场的人数,以及每个员工拿到的彩票的号码。线程运行后打印格式如下:
编号为: 2 的员工 从后门 入场! 拿到的双色球彩票号码是: [17, 24, 29, 30, 31, 32, 07]
编号为: 1 的员工 从后门 入场! 拿到的双色球彩票号码是: [06, 11, 14, 22, 29, 32, 15]
//.....
从后门入场的员工总共: 13 位员工
从前门入场的员工总共: 87 位员工
*
*双色球投注区分为红色球号码区和蓝色球号码区,红色球号码区由1-33共三十三个号码组成,蓝色球号码区由1-16共十六个号码组成。
*投注时选择6个红色球号码和1个蓝色球号码组成一注进行单式投注。

[code]public class Thread2 {
@Test
public void main() {
Meet m = new Meet();

Thread t1 = new Thread(m);
Thread t2 = new Thread(m);

t1.setName("前门");
t2.setName("后门");

t1.start();
t2.start();
}
}
class Meet implements Runnable{
List<Integer> red = new ArrayList<>();
List<Integer> blue = new ArrayList<>();
{
for(int i=1;i<=33;i++) {
red.add(i);
if(i<=16) {
blue.add(i);
}
}
}
int[] arr = new int[7];
int num = 0;
@Override
public void run() {
List<Integer> p = new LinkedList<>();
while(true) {
p.addAll(randomRed());
p.add(randomBlue());

synchronized(this){
if(num >= 100) break;
num++;
System.out.println("编号为"+num+"的员工 从"+Thread.currentThread().getName()+" 入场! 拿到的双色球彩票号码是:"+ p.toString());
p.clear();

}

}
}
public List<Integer> randomRed(){
List<Integer> list =new ArrayList<>();
Random r = new Random();
while(list.size() < 6) {
int a = r.nextInt(red.size())+1;
if(list.contains(a)) {
continue;
}
list.add(a);
}
return list;
}
public int randomBlue(){
Random r = new Random();

return r.nextInt(blue.size())+1;
}

}

4、启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7,8,9,10, 
然后是线程3打印11,12,13,14,15. 接着再由线程1打印16,17,18,19,20….以此类推, 直到打印到75(老师说:三个交替没意义)

这种做法投机取巧了,网上还有高级做法

[code]public class Thread3 {
@Test
public void main() {
Print p = new Print();
Thread t1= new Thread(p);
t1.setName("1");
Thread t2= new Thread(p);
t2.setName("2");
Thread t3= new Thread(p);
t3.setName("3");

t1.start();
t2.start();
t3.start();
}
}
class Print implements Runnable{
Object o = new Object();

int num = 0;
int j = 0;
int m = 1;
@Override
public void run() {
while(true) {
synchronized (o){
int id = Integer.valueOf(Thread.currentThread().getName());
if(id==m) {
if(num >= 75) {
break;
}
for(int i=1;i<6;i++) {
num++;
System.out.println("线程"+id+":"+(j*5+i));
}
j++;
m++;
if(m==4) m=1;
o.notifyAll();
}else {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

}

5、两个用户交替向同一个账户存钱各3次,每次1000元,并打印余额

[code]public class Thread6 {
@Test
public void main() {
Accounts ac = new Accounts();
User u = new User();
u.init(ac);
Thread t =new Thread(u,"用户1");
Thread t2 =new Thread(u,"用户2");
t.start();
t2.start();
}
}
class Accounts {
int balance;
public synchronized void add() {
notify();
balance+=1000;
System.out.println(Thread.currentThread().getName()+"当前余额:"+this.balance);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

}

}
class User implements Runnable{
Accounts ac;
public void init(Accounts ac) {
this.ac = ac;
}
@Override
public void run() {
for(int i=1; i<=3;i++) {
ac.add();
}
}

}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: