多线程的一些问题

------------------------------------------------------------------------------------------

1.使用同步代码块的方法解决同步线程的安全问题

package com.lanqiao.javatest;
/*
* 线程的同步,安全问题:打印车票出现重票,错票
* */
//存在安全性问题的原因是什么:

//使用同步代码块的方法实现进程同步出现的数据输出重复,不规范的问题
class Win extends Thread{
static int ticket=100;
Object obj=new Object();
public void run(){
while(true){
synchronized (obj) {//this,当前方法的对象
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(ticket>0){
System.out.println(Thread.currentThread().getName()+":"+ticket--);
}

}
}
}
}

public class ThreadTest {
public static void main(String[] args) {
Win w1=new Win();
Win w2=new Win();
Win w3=new Win();

w1.setPriority(Thread.MAX_PRIORITY);
w2.setPriority(Thread.NORM_PRIORITY);
w3.setPriority(Thread.MIN_PRIORITY);

w1.setName("线程1:");
w2.setName("线程2:");
w3.setName("线程3:");

w1.start();
w2.start();
w3.start();
}
}

------------------------------------------------------------------------------------------

2.使用同步方法,解决同步线程的程安全问题

package com.lanqiao.javatest;


//使用同步方法,解决进程同步问题
//在多线程中,当一个线程操作执行时,其他线程不能进入进行操作,直至此线程执行完后,其他线程才可以进入进行操作;
class Win1 extends Thread{
Object obj=new Object();
static int ticket=100;
public void run(){
while(true){
shou();
}
}
public synchronized void shou(){

try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(ticket>0){
System.out.println(Thread.currentThread().getName()+":"+ticket--);
}
}
}
public class ThreadTest1 {
public static void main(String[] args) {
Win1 w1=new Win1();
Win1 w2=new Win1();
Win1 w3=new Win1();

w1.setPriority(Thread.MAX_PRIORITY);
w2.setPriority(Thread.NORM_PRIORITY);
w3.setPriority(Thread.MIN_PRIORITY);

w1.setName("线程1:");
w2.setName("线程2:");
w3.setName("线程3:");

w1.start();
w2.start();
w3.start();
}
}

------------------------------------------------------------------------------------------

 3.同步代码块中使用wait(),notify(),notifyAll()[必须在同步代码块使用这三个方法]

package com.lanqiao.javatest;
//线程同步:wait():线程挂起,并且放弃cpu资源,不同于,sleep(线程挂起一段时间,时间一到继续抢夺cpu);
//notify(),notifyAll():唤醒被挂起的线程,使其继续抢夺cpu;
//三个方法使用时,必须在同步代码块或同步方法中实现
//练习:有两个线程一个一个的输出100之内的数
class Test implements Runnable{
static int num=1;
@SuppressWarnings("static-access")
@Override
public void run() {
while(true){
synchronized (this) {
notify();
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (num <= 100) {
System.out.println(Thread.currentThread().getName() + ":" + num);
num++;
} else {
break;
}
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

}

}
public class ThreadTest2 {
public static void main(String[] args) {
Test t=new Test();

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

t1.setName("线程1:");
t2.setName("线程2:");

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

------------------------------------------------------------------------------------------

4.同步线程的练习题:

(1)例题1:两个用户向同一账户中存钱,每人存钱三次,每次1000元

package com.lanqiao.javatest;
/*
* 练习:两个用户向同一账户中存钱,每人存钱三次,每次1000元
* 其中,建立类时:每个类中都有有参数或无参数的构造方法;然后有几个变量,方法实现
* */
class Account{
double balance=189;
public Account(){

}
//找共享数据时,加synchronized是,看变量balance在什么地方变换
public synchronized void deposit(double money){
balance+=money;
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+balance);
}
}
class Customer extends Thread{
Account account;
public Customer(Account account){
this.account=account;
}
public void run(){
for(int i=0;i<3;i++){
account.deposit(1000);
}

}
}

public class ThreadTest3 {
public static void main(String[] args) {
Account aa=new Account();

Customer c=new Customer(aa);
Customer d=new Customer(aa);

c.setName("线程1:");
d.setName("线程2:");

c.start();
d.start();
}
}

(2)例题2:生产者和消费者的问题

package com.lanqiao.javatest;
/*
*生产者和消费者的问题
*生产者:生产的产品超过20了,就停止生产,直到消费者使产品小于等于20时,再进行生产
*消费者:不断的消费产品
*店员:通过产品剩余的多少,
*少于等于20时,向消费者提供产品,
*大于20时,向生产者提出停产的通知,
*小于0时,向消费者提出没有产品了请等待;
*
* */
class Clerk{//店员
int produce;//不加值的话是从0开始的
public Clerk(){

}
public synchronized void addProduce(){//生产者生产

if(produce>=20){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
produce++;
System.out.println(Thread.currentThread().getName()+":生产了第"+produce+"个产品");
notifyAll();
}
}
public synchronized void subCustomerww(){//消费者消费
if(produce<=0){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{

System.out.println(Thread.currentThread().getName()+":消费了第"+produce+"个产品");
produce--;
notifyAll();
}
}
}

class Producer implements Runnable{//生产者
Clerk clerk;
public Producer(){}
public Producer(Clerk clerk){
this.clerk=clerk;
}
@SuppressWarnings("static-access")
public void run() {
System.out.println("生产者生产产品:");
while(true){
try {
Thread.currentThread().sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clerk.addProduce();
}
}
}
class Customerww implements Runnable{//消费者
Clerk clerk;
public Customerww(){

}
public Customerww(Clerk clerk){
this.clerk=clerk;
}

@SuppressWarnings("static-access")
public void run() {
System.out.println("消费者消费产品:");
while(true){
try {
Thread.currentThread().sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clerk.subCustomerww();
}
}

}
public class ThreadTest4 {
public static void main(String[] args) {
Clerk clerk=new Clerk();

Producer p=new Producer(clerk);
Customerww c=new Customerww(clerk);

Thread t1=new Thread(p);
Thread t2=new Thread(c);

t1.setName("线程1:");
t2.setName("线程2:");

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

原文地址:https://www.cnblogs.com/lxnlxn/p/5764477.html